diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/exception/AccessTokenNotValidException.java b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/exception/AccessTokenNotValidException.java index a0ffe60..e4fd941 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/exception/AccessTokenNotValidException.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/exception/AccessTokenNotValidException.java @@ -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); } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/AccessTokenService.java b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/AccessTokenService.java new file mode 100644 index 0000000..9db3834 --- /dev/null +++ b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/AccessTokenService.java @@ -0,0 +1,6 @@ +package com.justpickup.userservice.domain.jwt.service; + +public interface AccessTokenService { + + void checkAccessToken(String authorizationHeader); +} diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/AccessTokenServiceImpl.java b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/AccessTokenServiceImpl.java new file mode 100644 index 0000000..0c6cc0a --- /dev/null +++ b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/AccessTokenServiceImpl.java @@ -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"); + } + } +} diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/RefreshTokenServiceImpl.java b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/RefreshTokenServiceImpl.java index fcd9981..115a9ad 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/RefreshTokenServiceImpl.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/RefreshTokenServiceImpl.java @@ -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(); } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/web/AuthController.java b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/web/AuthController.java index 39cfd79..f679a11 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/jwt/web/AuthController.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/jwt/web/AuthController.java @@ -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 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 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 checkAccessToken(@RequestHeader(name = "Authorization") String authorization) { + + accessTokenService.checkAccessToken(authorization); + + return ResponseEntity.status(HttpStatus.OK) + .body(Result.createSuccessResult(null)); + } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/JwtTokenDto.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/JwtTokenDto.java index 9e1f015..6162ce6 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/JwtTokenDto.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/JwtTokenDto.java @@ -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; } } diff --git a/user-service/src/main/java/com/justpickup/userservice/global/exception/GlobalExceptionHandler.java b/user-service/src/main/java/com/justpickup/userservice/global/exception/GlobalExceptionHandler.java index 55d9c4a..e1e6473 100644 --- a/user-service/src/main/java/com/justpickup/userservice/global/exception/GlobalExceptionHandler.java +++ b/user-service/src/main/java/com/justpickup/userservice/global/exception/GlobalExceptionHandler.java @@ -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()); } diff --git a/user-service/src/main/java/com/justpickup/userservice/global/security/LoginAuthenticationFilter.java b/user-service/src/main/java/com/justpickup/userservice/global/security/LoginAuthenticationFilter.java index 1b6ad13..464b9cd 100644 --- a/user-service/src/main/java/com/justpickup/userservice/global/security/LoginAuthenticationFilter.java +++ b/user-service/src/main/java/com/justpickup/userservice/global/security/LoginAuthenticationFilter.java @@ -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 tokens = Map.of( - "access_token", accessToken + Map 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("로그인 실패!!"); - } } diff --git a/user-service/src/main/java/com/justpickup/userservice/global/utils/JwtTokenProvider.java b/user-service/src/main/java/com/justpickup/userservice/global/utils/JwtTokenProvider.java index 14c9d65..479174b 100644 --- a/user-service/src/main/java/com/justpickup/userservice/global/utils/JwtTokenProvider.java +++ b/user-service/src/main/java/com/justpickup/userservice/global/utils/JwtTokenProvider.java @@ -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 getRoles(String token) { return (List) getClaimsFromJwtToken(token).get("roles"); }