💡 .java를 클릭시 관련 커밋으로 이동💡
private final static int REFRESH_TOKEN_INDEX = 2;
@ApiResponse(responseCode = "200", description = "로그아웃 성공")
@PostMapping("/logout")
public JsonResult<?> logout(@RequestHeader(name = "Authorization") String token) {
List<String> tokens = Arrays.asList(token.split(" "));
if (tokens.size() == 3) {
authService.logout(tokens.get(REFRESH_TOKEN_INDEX));
return JsonResult.successOf("로그아웃 되었습니다.");
} else {
log.warn(">>>> Invalid Header Access : {}", ExceptionMessage.JWT_INVALID_HEADER.getText());
return JsonResult.failOf(ExceptionMessage.JWT_INVALID_HEADER.getText());
}
}
- HTTP 요청 헤더 중 "Authorization" 헤더를 String 타입의 token 파라미터로 받음
- Authorization 헤더의 값을 공백으로 분리하여 배열로 만든다
- token.size()==3 인 이유는 → BEARER + " " + accessToken + " " + refreshToken
@Transactional
public void logout(String refreshToken) {
refreshTokenService.logout(refreshToken);
}
logout Service 구현
// Logout 시 Redis에 저장된 RefreshToken 삭제
public void logout(String refreshToken) {
String sub = jwtService.extractAllClaims(refreshToken).getSubject();
RefreshToken rtk = refreshTokenRepository.findById(refreshToken).orElseThrow(() -> {
log.warn(">>>> Token Not Exist : {}", ExceptionMessage.REFRESHTOKEN_NOT_EXIST.getText());
throw new JwtException(ExceptionMessage.REFRESHTOKEN_NOT_EXIST);
});
// refreshToken 유효성 검사
if (!jwtService.isTokenValid(refreshToken, rtk.getRefreshToken())) {
log.warn(">>>> Token Validation Fail : {}", ExceptionMessage.REFRESHTOKEN_INVALID.getText());
throw new JwtException(ExceptionMessage.REFRESHTOKEN_INVALID);
}
refreshTokenRepository.delete(rtk);
log.info(">>>> {}'s RefreshToken id deleted.", sub);
}
로그아웃 하면 Redis에 저장된 RefreshToken을 삭제한다.
테스트
@AutoConfigureMockMvc
public class TestConfig {
public static final String AUTHORIZATION = "Authorization";
public static final String BEARER = "Bearer";
public static String createAuthorizationHeader(String accessToken, String refreshToken) {
return BEARER + " " + accessToken + " " + refreshToken;
}
TestConfig 추가
@Test
@DisplayName("로그아웃 실패 테스트 - 잘못된 토큰으로 요청시 예외 발생")
void logoutTestWhenInvalidToken() throws Exception {
String accessToken = "strangeToken";
String refreshToken = "strangeToken";
// when
mockMvc.perform(
get("/auth/logout")
.header(AUTHORIZATION, createAuthorizationHeader(accessToken, refreshToken)))
// then
.andExpect(status().isOk())
.andExpect(jsonPath("$.res_code").value(400))
.andExpect(jsonPath("$.res_msg").value(ExceptionMessage.JWT_MALFORMED.getText()));
}
@Test
@DisplayName("로그아웃 성공 테스트")
void logoutSuccessTest() throws Exception {
// given
User user = User.builder()
.name(expectedName)
.role(UserRole.USER)
.platformType(UserPlatformType.GOOGLE)
.platformId(expectedPlatformId)
.profileImageUrl(expectedProfileImageUrl)
.build();
User savedUser = userRepository.save(user);
HashMap<String, String> map = new HashMap<>();
map.put("role", savedUser.getRole().name());
map.put("name", savedUser.getName());
map.put("profileImageUrl", savedUser.getProfileImageUrl());
String accessToken = jwtService.generateAccessToken(map, user);
String refreshToken = jwtService.generateRefreshToken(map, user);
// when
mockMvc.perform(get("/auth/logout")
.contentType(MediaType.APPLICATION_JSON)
.header(AUTHORIZATION, createAuthorizationHeader(accessToken, refreshToken)))
// then
.andExpect(status().isOk())
.andExpect(jsonPath("$.res_code").value(200))
.andExpect(jsonPath("$.res_obj").value("로그아웃 되었습니다."));
}
@Test
@DisplayName("로그아웃 실패 테스트 - 잘못된 Header로 요청시 에러 발생")
void logoutWhenInvalidHeader() throws Exception {
mockMvc.perform(get("/auth/logout")
.contentType(MediaType.APPLICATION_JSON)
.header(AUTHORIZATION, "INVALID HEADER"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.res_code").value(400))
.andExpect(jsonPath("$.res_msg").value(ExceptionMessage.JWT_INVALID_HEADER.getText()));
}
로그아웃 Controller 테스트 동작 검증
잘못된 토큰으로 요청 → 로그아웃 실패 테스트
로그아웃 성공 테스트
잘못된 Header로 요청 → 로그아웃 실패 테스트
'Project > 깃터디 (gitudy)' 카테고리의 다른 글
[깃터디/Auth] 닉네임 중복검사 api 구현 (0) | 2024.05.10 |
---|---|
[깃터디/Auth] 회원 정보 조회 구현 (0) | 2024.05.10 |
[깃터디/Auth] 로그인 페이지 요청 구현 (0) | 2024.05.10 |
[깃터디/Auth] OAuth2 Login 구현 (0) | 2024.05.10 |
[깃터디] OAuth 2.0 (0) | 2024.05.10 |
댓글