Refresh가 첨가된 JWT를 araboza
- 우선 첫 로그인 시 server -> client 로 access token과 refresh token을 같이 보내준다.
- server에서 refresh token을 따로 in-memory db에 저장할 것이냐 rdb에 저장할 것이냐. 혹은 다른 방안이 있는가
- client 는 이 두개의 토큰을 모두 local에 저장하고 있어야 한다.
client -> server 로 매번 access token과 refresh 토큰을 같이 보낼 것이냐, access token이 만료되었을 때에만 refresh token과 함께 보낼것이냐전자의 경우 access token 만료 시에도 요청을 한번만 보내면 됨. 다만 모든 요청에 불필요하게 refresh token을 실어 request 패킷의 크기가 커진다는 단점 존재후자의 경우 access token이 만료되었다는 응답을 받은 뒤 client → server로 access token과 refresh token을 모두 header에 담아 다시 한번 요청을 보내야 한다는 단점 존재- 토큰 만료 응답을 받았을 때 리프레시 토큰을 이용해 별도의 재요청을 주는 flow로 진행해야 할 듯. 그렇지 않으면 client에서 매번 토큰이 재발급 됐는지를 확인해야하는 소요가 생김
- refresh token을 이용해 access token을 새로 재발급 해줄 때 refresh token 또한 재발급 해줄 것인가
- 보안성이나 사용성 모두 유리하니 당연히 이러는게 좋을듯?
기타
db에는 user id와 refresh token으로 이루어진 새로운 테이블이 필요하겠지?근데 따로 in-memory db를 둘 것이 아니라면, user table에 refresh token 칼럼을 추가하면 어떨까?
하다보니 생긴 궁금점
- 클라이언트가 리프레시 토큰을 이용해 토큰을 재발급 받으면 이를 원래 토큰에 덮어 씌우는 작업을 진행해야 할텐데 그렇다면 토큰이 재발급 됐는지 안됐는지 체크를 매 응답을 받을 때마다 해야하는건가? → 위의 2 번에서 후자를 선택하면 문제가 안됨
우리가 추가해야할 flow
- jwt access token을 발행해 주는 단계에서 refresh token을 함께 발행
- 발행된 refresh token을 db에 저장
- jwt access token이 만료됐을 시 만료 응답 전송
- refresh 요청이 오면 refresh token을 비교하는 작업 수행
- refresh token이 유효하다면 1번으로 회귀
- refresh token이 만료됐을 시 db에서 refresh token을 삭제하고 로그아웃
- refresh token이 db에 없다면??? 정상적인 flow는 아닐 것으로 예상되나 로그아웃 시켜주면 문제는 없음
코드 수정
- 일 단
UserDto
에서 한개만 주던 토큰을 두개 줘야하니 추가.
public class UserDto { private final String accessToken; private final String refreshToken; private final String username; private final String group; public UserDto(String accessToken, String refreshToken, String username, String group) { this.accessToken = accessToken; this.refreshToken = refreshToken; this.username = username; this.group = group; } public String getAccessToken() { return accessToken; } public String getRefreshToken() { return refreshToken; } public String getUsername() { return username; } public String getGroup() { return group; } @Override public String toString() { return "UserDto{" + "accessToken='" + accessToken + '\'' + ", refreshToken='" + refreshToken + '\'' + ", username='" + username + '\'' + ", group='" + group + '\'' + '}'; } }
UserDto
를 생성하는UserRestController
에서는JwtAuthenticationToken
의 정보를 이용해UserDto
를 생성한다.JwtAuthenticationToken
에는 user 객체 또한 담겨있으므로