2023. 9. 8. 14:11ㆍDevelopment
안녕하세요!
이번 시간엔 정말 정말 정말로 토큰에 대한 구현을 마무리해보려고 해요.
그리고 테스트까지 진행해서 우리가 원하는 대로 돌아가는지 확인도 해볼게요.
오늘 구현은 매우 쉬우니 안심하셔도 돼요.
마음 편하게 읽어주세요.
이 게시물은 Refresh Token에 대해 다루고 있고, 설계와 Access Token의 후행 단계예요.
설계에 관한 글을 보고 오시지 않은 분들은 이 게시물을 먼저 보는 것을 추천 드릴게요.
JWT 기반 인증 2편 - 스프링 시큐리티 JWT 설계
안녕하세요! 이번 시간에는 스프링 시큐리티에서 JWT의 인증 흐름을 다뤄보려고 해요. 스프링 시큐리티에서 JWT를 구현하기 위한 설계 단계라고 봐주셨으면 좋겠어요. 소프트웨어 공학에서는 설
dalmeng-commeng.tistory.com
Access Token의 구현에 관한 글을 보고 오시지 않은 분들은 이 게시물을 먼저 보는 것을 추천드릴게요.
JWT 기반 인증 3편 - 스프링 시큐리티 JWT 인증 · 인가 구현 (1)
안녕하세요! 지금부터 본격적인 구현에 들어가 보려고 해요. 저번 시간에 정리한 설계 순서대로 구현을 할 예정이니, 이전 게시물을 보고 오시는 것을 추천드려요. https://dalmeng-commeng.tistory.com/4 J
dalmeng-commeng.tistory.com
이 프로젝트에서 작성한 모든 코드는 달맹의 깃허브에 있어요!
GitHub - dalmengs/tokenBasedAuthentication: Token Based Authentication in Spring Security
Token Based Authentication in Spring Security. Contribute to dalmengs/tokenBasedAuthentication development by creating an account on GitHub.
github.com
이번 시간에는 저번 시간에 끝내지 못한 구현을 전부 끝내고 테스트까지 진행해볼게요.
1. JWT란? - What is JWT?
2. 스프링 시큐리티 JWT 설계
3. 스프링 시큐리티에서 JWT 인증 · 인가 구현
4. Refresh Token 도입
4 - 1. Refresh Token 개요
4 - 2. 이전과 달라지는 점
4 - 3. 설정 파일 수정
4 - 4. JWT Provider 구현
4 - 5. JWT Filter 구현
4 - 6. 서비스 계층 구현 - Service Layer
4 - 7. 컨트롤러 계층 구현 - Controller Layer
4 - 8. 테스트 - Tests
5. 리팩토링
4 - 6. 서비스 계층 구현 - Service Layer
Refresh Token 생성 기능만 넣어주면 돼요.
이 기능은 역시 JWT Provider에 정의되어 있어서 주입받아 사용만 해줄게요.
public String createRefreshToken(String username){
return jwtUtil.createRefreshToken(username);
}
4 - 7. 컨트롤러 계층 구현 - Controller Layer
로그인이 성공하면 사용자에게 토큰을 다시 돌려줬었죠?
하지만 이제는 Refresh Token까지 돌려줘야 해서 Response DTO가 조금 수정되었어요.
크게 수정되진 않았고, Refresh Token 필드가 새로 생겼어요.
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AuthenticationResponseDto {
private String accessToken;
private String refreshToken;
private String username;
}
기존 코드는 Access Token을 요청하고, 받은 토큰을 헤더에 넣어주었죠?
여기서 Refresh Token도 같이 요청하고, 받은 토큰을 헤더가 같이 넣어주면 돼요.
거의 수정된 내용이 없어요.
@PostMapping("/login")
public BaseResponse login(@RequestBody AuthenticationRequestDto authenticationRequest, HttpServletResponse response){
try{
User user = authenticationService.login(authenticationRequest.getUsername(), authenticationRequest.getPassword());
String token = authenticationService.createToken(user);
String refreshToken = authenticationService.createRefreshToken(authenticationRequest.getUsername());
response.setHeader("access_token", token);
response.setHeader("refresh_token", refreshToken);
log.info("Access Token Created - Username : " + user.getUsername());
return BaseResponse.OK(new AuthenticationResponseDto(token, refreshToken, user.getUsername()));
}
catch (BaseException e){
return BaseResponse.FAILED(e.getResultCode(), e.getMsg());
}
catch (Exception e){
return BaseResponse.FAILED();
}
}
4 - 8. 테스트 - Tests
벌써 구현이 다 끝나서 바로 테스트를 진행해볼게요.
Access Token에 의한 인증 테스트는 예전에 진행했으므로 이번에는 생략할게요.
제가 진행할 테스트 목록은 아래와 같아요.
- 로그인에 성공하면 Refresh Token도 같이 돌려주는가?
- Access Token과 Refresh Token이 모두 만료되면 요청이 실패하는가?
- Access Token이 만료되었어도 Refresh Token이 만료되지 않았으면 요청을 성공적으로 처리할 수 있는가?
1. 로그인에 성공하면 Refresh Token도 같이 돌려주는가?
기존과 똑같이 로그인 요청을 해주었어요.
{
"username": "dalmeng",
"password": "********"
}
예상한 대로 Access Token과 Refresh Token이 같이 온 것을 확인할 수 있죠?

[2 ~ 3] 원활한 테스트를 위해 Access Token의 만료 시간은 10초, Refresh Token의 만료시간은 30초로 설정해주었어요.
2. Access Token과 Refresh Token이 모두 만료되면 요청이 실패하는가?
똑같이 로그인을 한 후, 아래 그림과 같이 Access Token과 Refresh Token을 모두 헤더에 넣어 요청해주었어요.

아래 그림과 같이 모든 토큰이 만료되어 요청이 실패한 것을 알 수 있죠?

조금 더 자세한 분석을 위해 로그를 볼게요.

- 12시 41분 55초 - Access Token, Refresh Token 생성
- 12시 42분 05초 - Access Token 만료
- 12시 42분 25초 - Refresh Token 만료
- 12시 42분 47초
- 자원 접근 요청
- 유효하지 않은 토큰 (Invalid Token)
- 요청 거부
원하는 대로 두 토큰이 모두 만료되었을 때는 자원 접근 요청을 성공적으로 거부했어요.
3. Access Token이 만료되었어도 Refresh Token이 만료되지 않았으면 요청을 성공적으로 처리할 수 있는가?
똑같은 형식으로 로그인하고, 재요청 시간만 달리 했어요.
Access Token은 만료되었지만 Refresh Token이 아직 살아있을 때 요청했어요.

이번에는 예상대로 요청이 성공한 것을 알 수 있죠?
예상대로라면 Refresh Token을 확인하고 Access Token을 재발급했어야 돼요.
원하는 대로 흘러갔는지 로그를 확인해볼게요.

- 12시 47분 47초 - Access Token, Refresh Token 생성
- 12시 47분 57초 - Access Token 만료
- 12시 48분 06초
- 자원 접근 요청
- Access Token 만료 확인
- 유효한 Refresh Token
- Access Token 재생성
- 요청 승인
- 12시 48분 17초 - Refresh Token 만료
모든 테스트를 성공적으로 마무리 했고, Refresh Token을 도입하는데 성공했어요.
Access Token의 유효 시간이 길면 Refresh Token을 도입한 이유가 퇴색된다는 것을 꼭 이해하고, 적절한 유효 시간을 설정해야 해요.
지금까지 정말 고생많으셨고, 다음 시간에는 리팩토링 시간으로 돌아올게요.
제 글이 많은 도움이 되었길 바라며,
긴 글 봐주셔서 감사합니다!
멋진 개발자가 되기 위해 더 열심히 달리겠습니다!
- 달맹 -
'Development' 카테고리의 다른 글
| 객체 지향 프로그래밍 1편 - 간단한 설명과 예시 (0) | 2024.03.04 |
|---|---|
| JWT 기반 인증 8편 [끝] - 리팩토링 (0) | 2023.09.09 |
| JWT 기반 인증 6편 - Refresh Token 도입 (1) (0) | 2023.09.08 |
| JWT 기반 인증 5편 - 스프링 시큐리티 JWT 인증 · 인가 구현 (3) (0) | 2023.09.08 |
| JWT 기반 인증 4편 - 스프링 시큐리티 JWT 인증 · 인가 구현 (2) (1) | 2023.09.07 |