Access Token
Access Token이 탈취를 당하면 큰 일이 난다.
그래서 이걸 방지하려고 AccessToken의 만료기한을 짧게 설정하는데, 이러면 사용자 경험이 나빠지게 된다.
계속 로그인을 해야하니까!
그래서 이 해결법으로 나온 게 Refresh Token이다
Refresh Token
Refresh Token은 Access Token 이 만료 됐을 때 Access Token 을 재발급 해주기 위해서 사용한다
프로세스
기본적인 개념은 아래와 같다
- Access Token
- 만료기한이 짧다
- Refresh Token
- 만료기한이 길다
평소 API 통신에서는 Access Token을 사용하고, Refresh Token은 Access Token이 만료되어 갱신 될 때 사용한다.
Refresh Token 순서
- 로그인 인증을 성공한 클라이언트는 서버로 부터 Access Token, Refresh Token을 발급 받는다
- 클라이언트는 위 Token 두 개를 로컬 스토리지에 저장한다
- 클라이언트는 Header에 Access Token을 넣고 API 통신을 한다
- Access Token의 만료 기한이 끝나면??
- Access Token이 유효하지 않아서 권한이 없는 사용자가 된다
- 유효기간이 만료된 Token을 받은 서버는 에러 코드로 응답한다
- 클라이언트는 만료된 토큰임을 알 수 있다
- Header에 Refresh Token을 넣어서 API를 재요청 한다
- Refresh Token의 권한을 확인한 서버는 Response Header에 새로운 Access Token을 넣어서 응답한다
- 만약 Refresh Token도 만료 되었다면 서버는 동일하게 에러 코드로 응답하고 클라이언트는 재로그인을 해야한다
이러한 Refresh Token의 유효성 검증을 하기 위해서는 서버 측에서 Refresh Token을 저장해야하기 때문에 데이터 베이스를 사용하지 않고서는 구현할 수 가 없다.
완전한 Stateless 방식으로는 Refresh Token을 통한 Access Token 재발급을 구현할 수 없다.
일반적으로 Refresh Token은 Access Token의 만료시간이 지난 후에 새로운 Access Token을 발급 받기위해 사용한다.
이 과정에서 Refresh Token은 서버에 저장되어야 한다.
그래야 Refresh Token을 사용한다는 의미가 생기고 유효성 검증을 통해 새로운 Access Token을 발급하는 작업이 필요하다.
아주 약간의 Stateful 방식을 추가해서 사용자 경험을 올리고 Stateless 방식의 이점도 살리는 것이다.
이때 추천하는 DB가 Redis인데 Redis를 쓰는 이유에 대해서 알아보자
Refresh Token DB로 Redis를 왜 써?
Redis를 왜 쓰는지 알아야 되는데 우선 Redis의 특징부터 알아보자
Redis
- 인 메모리 DB
- Key - Value 형식으로 되어있다
- 그래서 스키마가 존재하지 않고 테이블도 없다는 특징을 갖고 있다.
- 메모리에 저장한다
- 단순하고 빠르다
- NoSQL
- 검증을 안 하고 바로 덮어 씌우면 된다 - 휘발성이 강하다
Redis는 이런 특징을 가지고 있다.
여기서 집중해야할 것이 휘발성이 강하다는 특징이다.
자바 자료구조의 Map 처럼 Redis에 저장할 때 Key가 중복되면 Value를 덮어 씌운다.
따로 검증같은 것을 안 한다.
관계형 DB에서는 내부적으로 관계가 형성되어 있고 데이터끼리 연관관계가 있어서 검증을 해야하고 저장 형식에 맞지 않으면 저장을 하지 않는다.
근데 Redis는 검증 안하고 단순하게 바로 덮어 씌운다. 그래서 빠르다
이러한 단순하고 빠른 특성 때문에 Refresh Token의 DB로 Redis를 많이 채택하는 것이다
Stateless 방식에서 Stateful을 약간 추가했는데 Stateful의 추가로 속도적인 부분에서 Stateless 와 비슷한 속도가 안나오면 Token을 쓰는 의미가 없어지니 단순하고 빠른 Redis를 사용하는 것이다.
'TIL' 카테고리의 다른 글
TIL 2023-12-11 명시적 삭제 컬럼 (0) | 2023.12.11 |
---|---|
TIL 2023-12-08 getWriter() has already been called for this response (0) | 2023.12.08 |
TIL 2023-12-06 jwt 로그인 시 unsuccessfulAuthentication로 계속 빠진다면? (0) | 2023.12.06 |
TIL 2023-12-05 Entity에 대한 JPA 테스트는 어떻게 할까? (0) | 2023.12.05 |
TIL 2023-12-01 Mockito any()를 쓰는 이유 (0) | 2023.12.01 |