티스토리 뷰
JWT를 통한 인증 절차
1.[프론트엔드] ID와 비밀번호를 준다.
2.[백엔드] ID와 비밀번호를 검증하고 AccessToken과 RefreshToken, AccessToken의 만료시간을 반환해준다. 이 때 생성한 RefreshToken은 DB에 {ID,RefreshToken}으로 저장한다.
3.[프론트엔드] 반환받은 AccessToken을 매 api 호출마다 헤더에 붙여서 전송한다.
4.[백엔드] api 호출시 헤더의 AccessToken을 확인하고 유효한지, 만료기간이 지났는지를 체크 후 api를 동작시킨다.
5.[프론트엔드] AccessToken의 만료기간이 지나거나, 30초 미만으로 남았다면, 백엔드에 RefreshToken을 붙여 Reissue요청을 보낸다.
6.[백엔드]Reissue 요청이 들어올 경우, RefreshToken이 DB에 있는 것인지 확인한 후, 맞다면 AccessToken과 새로운 AccessToken 만료 시간을 반환한다.
7.[프론트엔드] Reissue결과 반환된 AccessTolen과 만료기간을 저장하여 다음 api호출에 사용한다.
JWT 개념
accessToken만 생각했을 때 개념을 생각해보면, 로그인시 백엔드에서 암호화된 AcessToken을 주고, 프론트에서 api요청마다 AccessToken을 헤더에 첨부하여 사용자가 누구인지 백엔드에 알려주는것이다.
1.[프론트엔드] ID와 비밀번호를 준다.
2. [백엔드] ID와 비밀번호를 검증하고 AccessToken을 반환한다.
3. [프론트엔드] AccessToken을 받아 다음 api호출부터 헤더에 붙여준다.
4. [백엔드] api호출시 AccessToken이 유효한지 확인하여 처리한다.
이렇게 간단하게 구현한 방식에 가장 큰 단점은 AccessToken이 한번 탈취당할 경우, 공격자가 무제한을 api에 접근하여 정보를 채갈 수 있다. 그래서 만료시간이라는 개념이 나오는데, AccessToken을 발급할 때, 10분 혹은 30분으로 제한 시간을 둬서 시간이 지난 후에는 해당 AccessToken으로 접근할 수 없게 하는 것이다.
1.[프론트엔드] ID와 비밀번호를 준다.
2. [백엔드] ID와 비밀번호를 검증하고 AccessToken을 반환한다.이 때 만료시간을 설정한다.
3. [프론트엔드] AccessToken을 받아 다음 api호출부터 헤더에 붙여준다.
4. [백엔드] api호출시 AccessToken이 유효한지 확인하여 처리한다.만료시간이 지나지 않았는지 확인하여 처리한다.
그러나, 이 경우 사용자가 10분, 30분마다 재 로그인을 해야한다는 문제가 생긴다. 이를 보완하기 위해 생긴것이 바로
RefreshToken이라는 개념이 등장한다. 만료시간이 지났을 경우 RefreshToken을 통해AccessToken을 재발급 받을 수 있도록 구현하는 것이다.
여기서 의문이 생길 수 있다. 그럼 RefreshToken을 탈취당하면 무제한으로 AccessToken을 발급받을 수 있는 것이 아닌가? 맞다.. 따라서 RefeshToken을 더 안전한 곳에 보관할 것을 권장하고 있다. 그럼 애초에 AccessToken을 안전하게 보관하면 되는 문제가 아닌가? ..
이에대한 문제는 해당 링크에서 참고하면 될듯하다.
1. [프론트엔드] ID와 비밀번호를 준다.
2. [백엔드] ID와 비밀번호를 검증하고 AccessToken, RefreshToken을 반환한다. 이 때 AccessToken의 만료시간을 설정한다.
3. [프론트엔드] AccessToken을 받아 다음 api호출부터 헤더에 붙여준다. RefreshToken은 안전한 곳에 보관한다.
4. [백엔드] api호출시 AccessToken이 유효한지, 만료시간이 지나지 않았는지 확인하여 처리한다.
5. [프론트엔드] 만약 AccessToken이 만료되어 api 동작이 실패하였다면, RefreshToken을 백엔드에 줘서 Reissue를 건다.
6. [백엔드] Reissue요청이 오면, AccessToken을 새로 만들어 반환한다.
여기에서 RefreshToken의 가장 큰 문제점은 RefreshToken이 탈취될 경우 공격자가 무제한으로 AccessToken을 재발급 받을 수 있다는 것이다. 그래서 가장 최신의 RefreshToken을 DB에 저장하는 방식을 채택한다. 로그인할 때 새로운 RefreshToken을 발급하고, 동시에 DB에 저장한다. Reissue시에는 RefreshToken이 DB에 저장된 것과 같은지 비교한다. 이렇게하면 다른 환경에서 새로 로그인할 경우, 기존의 RefreshToken은 설령 만료 기간이 남았더라도 사용할 수 없게 된다.
이 방식에서는 api를 보내보고 실패할 경우 > reissue를 거는 방식이라 불필요한 api호출이 최소 한 번은 일어나게 된다. 그렇다면 AccessToken의 만료시간을 백엔드로부터 전달받아 만료시간이 다 되었다면 api를 호출하지 않고 Reissue를 먼저 호출한 후 api를 호출하도록 구현할 수 있다.
여기에 더해 고려애햐하는 것이 만료시간인데 프론트엔드에서 백엔드로 api를 요청하는 데는 시간이 걸린다. AccessToken의 만료 시간은 1:10이다. 사용자는 1:09에 api를 호출했다. 프론트엔드에서는 1:10이 지나지 않았기 때문에 Reissue를 하지 않고 그대로 백엔드로 보낸다. 그러나 백엔드에서는 1:10에 api요청을 받는다. 백엔드 입장에선 AccessToken이 만료되었기 때문에 이 api요청은 거부된다. 이 문제를 해결하기 위하여, 프론트엔드에서는 단순히 AccessToken의 만료시간이 지났는지를 기준으로 삼는 것이 아니라, 만료시간이 적게 남았을 경우 + 만료시간이 지났을 경우로 조건을 바꾸어 주어야 한다.
1. [프론트엔드] ID와 비밀번호를 준다.
2. [백엔드] ID와 비밀번호를 검증하고 AccessToken, RefreshToken, AccessToken의 만료시간을 반환해준다. 이 때 생성한 RefreshToken은 DB에 {ID, RefreshToken}으로 저장한다.
3. [프론트엔드] 반환받은 AccessToken을 매 api호출마다 헤더에 붙여준다.
4. [백엔드] api호출시 AccessToken을 확인하고 유효한지, 만료기간이 지났는지를 체크 후 api를 동작시킨다.
5. [프론트엔드] 만약 AccessToken이 만료기간이 지나거나, 30초 미만으로 남았다면,백엔드에 RefreshToken을 붙여 Reissue 요청을를 보낸다.
6. [백엔드] Reissue요청이 오면,RefreshToken이 DB에 있는 것인지 확인한 후, 맞다면 AccessToken과 새로운 AccessToken 만료시간을 반환한다.
7. [프론트엔드] Reissue결과 반환된 AccessToken과 만료기간을 저장하여 다음 api호출에 사용한다.
'기타' 카테고리의 다른 글
CI/CD 와 GitHub Actions (0) | 2023.10.06 |
---|---|
Node.js의 Timers (0) | 2022.09.28 |
Jest 유닛테스트(2) - Jest Mocking Modules (0) | 2022.02.12 |
Jest 유닛테스트(1)-[Jest] jest.fn() 함수 (0) | 2022.02.12 |
Swagger란? (0) | 2022.02.05 |
- Total
- Today
- Yesterday
- 알고리즘
- 결제기능
- 더미데이터
- 항해솔직후기
- http
- 항해플러스후기
- 레포지토리패턴
- 시스템설계
- vue3
- 개발자
- vite
- 항해플러스프론트엔드
- React18v
- event종류
- react
- 회고
- Repository pattern
- 디자인시스템
- 이벤트리스너
- JWT토큰
- eventListner
- Vue.js
- store.js
- 그림으로 이해하는 시스템 설계
- vue.js3
- props
- focus와blur
- 구름톤
- 프로덕트설계
- 로그인 인증
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |