AccessToken 재발급 프로세스
2021. 6. 28. 21:46ㆍSpring Security/Spring Boot Jwt with JPA and Redis
반응형
AccessToken 재발급은 앞에서 설명한 대로 만료시간을 짧게 설정하기 때문에 로그인을 자주 요청할 수 있게 된다. 이를 보완하기 위하여 AccessToken 이 만료되고, RefreshToken 이 유효하다면 사용자가 사이트를 이용하는 동안에 서버에서 자동으로 AccessToken을 재발급 함으로써 로그인 없이 사이트를 이용할 수 있도록 한다.
아래 그림은 AccessToken 재발급의 시퀀스다이어그램 입니다.
JwtFilter
// AccessToken 재발급인 경우
if (!isValidAccessToken && isValidRefreshToken) {
// AccessToken 재발급
accessToken = reIssueAccessToken(refreshToken);
// 쿠키 생성
CookieUtil cookieUtil = new CookieUtil();
httpServletResponse.addCookie(cookieUtil.createCookie(ACCESS_TOKEN_COOKIE_NAME, accessToken, "A"));
// 재발급 AccessToken 유효성 체크
isValidAccessToken = validateAccessToken(accessToken);
}
/**
* AccessToken 재발급
*
* @param refreshToken
* @return refreshToken 재발급 AccessToken
*/
private String reIssueAccessToken(String refreshToken) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>(refreshToken, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity( "http://localhost:10001/token/re-issue/access-token", request , String.class);
return responseEntity.getBody();
}
/**
* AccessToken 유효성 체크
*
* @param accessToken
* @return true or false
*/
private Boolean validateAccessToken(String accessToken) {
return jwtUtil.validateToken(accessToken);
}
1. auth-server에 AccessToken을 재발급을 받는다.
2. accessTokenCookie를 생성한다.
3. 재발급받은 토큰의 유효성을 체크한다.
TokenController.reIssueAccessToken
/**
* AccessToken 재발급
*
* @param refreshToken Base64로 암호화된 값이므로 서비스 호출전 Decoding 처리 해얗 함
* @return ResponseEntity<String> 재발급된 accessToken
*/
@PostMapping("/re-issue/access-token")
public ResponseEntity<String> reIssueAccessToken(@RequestBody String refreshToken) throws Exception {
String accessToken = authService.generateAccessTokenFromRefreshToken(AES256Cipher.decrypt(refreshToken));
return new ResponseEntity<>(accessToken, HttpStatus.OK);
}
refreshToken은 암호화되어 있으므로 서버에서 복호화 처리를 해줘야 한다.
AuthService.generateAccessTokenFromRefreshToken
@Override
public String generateAccessTokenFromRefreshToken(String refreshToken) throws Exception {
String accessToken = null;
// 전달받은 RefreshToken 정보로 Redis 서버에 저장된 사용자 ID 조회
logger.debug("refreshToken({})", refreshToken);
Optional<RefreshToken> token = Optional.ofNullable(refreshTokenRepository.findById(refreshToken)
.orElseThrow(() -> new TokenNotFoundException("RefreshToken 이 존재하지 않습니다.")));
// AccessToken 재밣행
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(token.get().getUsername(),
AES256Cipher.decrypt(token.get().getPassword()));
Authentication authentication = null;
try {
authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
} catch (BadCredentialsException e) {
throw new BadCredentialsException("[" + token.get().getUsername() + "] 사용자 정보가 존재 하지 않습니다.");
}
accessToken = tokenProvider.createToken(authentication);
logger.debug("AccessToken({}) 이 정상적으로 발급 되었습니다.", accessToken);
return accessToken;
}
1. Authentication 객체를 생성하기 위해서 Redis Server에 저장된 사용자 정보를 조회한다.
2. Authentication 객체를 생성한다.
3. TokenProvider에 토큰 생성을 요청한다.
4. 재발급된 accessToken을 반환한다.
반응형
'Spring Security > Spring Boot Jwt with JPA and Redis' 카테고리의 다른 글
RefreshToken 재발급 프로세스 (0) | 2021.07.02 |
---|---|
AccessToken 재발급 테스트 (0) | 2021.07.02 |
로그인 테스트 (0) | 2021.06.27 |
로그인 프로세스 (0) | 2021.06.27 |
프로젝트 소개 및 설정 (0) | 2021.06.27 |