feat(user-service): JWT 토큰 관련 로직 변경

- access token 재발급 시 response body에 만료 시간 추가
- 페이지 이동 시 사용할 access token check 로직 추가
This commit is contained in:
bum12ark
2022-02-28 16:54:16 +09:00
parent b6b3e39380
commit 5f46d73a22
9 changed files with 70 additions and 25 deletions

View File

@@ -6,6 +6,6 @@ import org.springframework.http.HttpStatus;
public class AccessTokenNotValidException extends CustomException {
public AccessTokenNotValidException(String message) {
super(HttpStatus.FORBIDDEN, message);
super(HttpStatus.UNAUTHORIZED, message);
}
}

View File

@@ -0,0 +1,6 @@
package com.justpickup.userservice.domain.jwt.service;
public interface AccessTokenService {
void checkAccessToken(String authorizationHeader);
}

View File

@@ -0,0 +1,23 @@
package com.justpickup.userservice.domain.jwt.service;
import com.justpickup.userservice.domain.jwt.exception.AccessTokenNotValidException;
import com.justpickup.userservice.global.utils.JwtTokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class AccessTokenServiceImpl implements AccessTokenService {
private final JwtTokenProvider tokenProvider;
@Override
public void checkAccessToken(String authorizationHeader) {
String token = authorizationHeader.replace("Bearer", "");
if (!tokenProvider.validateJwtToken(token)) {
throw new AccessTokenNotValidException("Access Token is not Valid");
}
}
}

View File

@@ -19,6 +19,7 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@@ -69,9 +70,11 @@ public class RefreshTokenServiceImpl implements RefreshTokenService {
.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
String newAccessToken = jwtTokenProvider.createJwtAccessToken(userId, "/refreshToken", roles);
Date expiredTime = jwtTokenProvider.getExpiredTime(newAccessToken);
return JwtTokenDto.builder()
.accessToken(newAccessToken)
.accessTokenExpiredDate(expiredTime)
.refreshToken(refreshToken)
.build();
}

View File

@@ -1,6 +1,7 @@
package com.justpickup.userservice.domain.jwt.web;
import com.justpickup.userservice.domain.jwt.service.RefreshTokenServiceImpl;
import com.justpickup.userservice.domain.jwt.service.AccessTokenService;
import com.justpickup.userservice.domain.jwt.service.RefreshTokenService;
import com.justpickup.userservice.domain.user.dto.JwtTokenDto;
import com.justpickup.userservice.global.dto.Result;
import com.justpickup.userservice.global.utils.CookieProvider;
@@ -15,20 +16,22 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.ws.rs.core.HttpHeaders;
import java.text.SimpleDateFormat;
@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
@Slf4j
public class AuthController {
private final RefreshTokenServiceImpl refreshTokenServiceImpl;
private final RefreshTokenService refreshTokenService;
private final AccessTokenService accessTokenService;
private final CookieProvider cookieProvider;
@GetMapping("/refreshToken")
@GetMapping("/reissue")
public ResponseEntity<Result> refreshToken(@RequestHeader("X-AUTH-TOKEN") String accessToken,
@CookieValue("refresh-token") String refreshToken) {
JwtTokenDto jwtTokenDto = refreshTokenServiceImpl.refreshJwtToken(accessToken, refreshToken);
JwtTokenDto jwtTokenDto = refreshTokenService.refreshJwtToken(accessToken, refreshToken);
ResponseCookie responseCookie = cookieProvider.createRefreshTokenCookie(refreshToken);
@@ -42,9 +45,12 @@ public class AuthController {
@AllArgsConstructor
static class RefreshTokenResponse {
private String accessToken;
private String expiredTime;
public RefreshTokenResponse(JwtTokenDto jwtTokenDto) {
this.accessToken = jwtTokenDto.getAccessToken();
this.expiredTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(jwtTokenDto.getAccessTokenExpiredDate());
}
}
@@ -52,7 +58,7 @@ public class AuthController {
public ResponseEntity<Result> logout(@RequestHeader("X-AUTH-TOKEN") String accessToken,
@RequestHeader("REFRESH-TOKEN") String refreshToken) {
refreshTokenServiceImpl.logoutToken(accessToken);
refreshTokenService.logoutToken(accessToken);
ResponseCookie refreshCookie = cookieProvider.removeRefreshTokenCookie();
@@ -60,4 +66,13 @@ public class AuthController {
.header(HttpHeaders.SET_COOKIE, refreshCookie.toString())
.body(Result.createErrorResult(""));
}
@GetMapping("/check/access-token")
public ResponseEntity<Result> checkAccessToken(@RequestHeader(name = "Authorization") String authorization) {
accessTokenService.checkAccessToken(authorization);
return ResponseEntity.status(HttpStatus.OK)
.body(Result.createSuccessResult(null));
}
}

View File

@@ -3,14 +3,18 @@ package com.justpickup.userservice.domain.user.dto;
import lombok.Builder;
import lombok.Getter;
import java.util.Date;
@Getter
public class JwtTokenDto {
private String accessToken;
private Date accessTokenExpiredDate;
private String refreshToken;
@Builder
public JwtTokenDto(String accessToken, String refreshToken) {
public JwtTokenDto(String accessToken, String refreshToken, Date accessTokenExpiredDate) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.accessTokenExpiredDate = accessTokenExpiredDate;
}
}

View File

@@ -36,7 +36,7 @@ public class GlobalExceptionHandler {
// 쿠키 삭제
ResponseCookie responseCookie = cookieProvider.removeRefreshTokenCookie();
return ResponseEntity.status(HttpStatus.FORBIDDEN)
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.header(HttpHeaders.SET_COOKIE, responseCookie.toString())
.body(e.getResult());
}

View File

@@ -18,11 +18,12 @@ import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -70,6 +71,7 @@ public class LoginAuthenticationFilter extends UsernamePasswordAuthenticationFil
String userId = user.getUsername();
String accessToken = jwtTokenProvider.createJwtAccessToken(userId, request.getRequestURI(), roles);
Date expiredTime = jwtTokenProvider.getExpiredTime(accessToken);
String refreshToken = jwtTokenProvider.createJwtRefreshToken();
refreshTokenServiceImpl.updateRefreshToken(Long.valueOf(userId), jwtTokenProvider.getRefreshTokenId(refreshToken));
@@ -83,17 +85,11 @@ public class LoginAuthenticationFilter extends UsernamePasswordAuthenticationFil
response.addCookie(cookie);
// body 설정
Map<String, String> tokens = Map.of(
"access_token", accessToken
Map<String, Object> tokens = Map.of(
"accessToken", accessToken,
"expiredTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(expiredTime)
);
new ObjectMapper().writeValue(response.getOutputStream(), Result.createSuccessResult(tokens));
}
@Override
protected void unsuccessfulAuthentication
(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException {
log.warn("로그인 실패!!");
}
}

View File

@@ -5,10 +5,6 @@ import io.jsonwebtoken.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import java.util.Date;
@@ -57,8 +53,6 @@ public class JwtTokenProvider {
.compact();
}
public String getUserId(String token) {
return getClaimsFromJwtToken(token).getSubject();
}
@@ -75,6 +69,10 @@ public class JwtTokenProvider {
return getClaimsFromJwtToken(token).get("value").toString();
}
public Date getExpiredTime(String token) {
return getClaimsFromJwtToken(token).getExpiration();
}
public List<String> getRoles(String token) {
return (List<String>) getClaimsFromJwtToken(token).get("roles");
}