From 925ff62f6b8fd92031935e17e4034d111376327f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 18:33:55 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20AuthController=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회원가입 API 요청 데이터 검증 추가 - 로그인 API 수정 --- .../auth/controller/AuthController.java | 17 +++++------------ .../server/auth/dto/SignupRequest.java | 19 +++++-------------- .../server/auth/service/AuthService.java | 13 ++++++++----- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 77853a38..68d96bef 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -5,8 +5,8 @@ import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.user.domain.OAuthProvider; import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import java.io.IOException; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -34,21 +34,14 @@ public ResponseEntity redirectAuthCodeRequestUrl(@PathVariable OAuthProvid } @PostMapping("/sign-up") - public ResponseEntity signup(@RequestBody SignupRequest request) { + public ResponseEntity signup(@Valid @RequestBody SignupRequest request) { return ResponseEntity.ok(authService.signup(request)); } @GetMapping("/login/{oAuthProvider}") - public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, - @RequestParam String authCode, HttpServletResponse response) throws IOException { - Optional authTokens = authService.login(oAuthProvider, authCode); - if (authTokens.isPresent()) { - return ResponseEntity.ok(authTokens.get()); - } - - String signupUrl = "/oauth2/auth/sign-up"; - response.sendRedirect(signupUrl); - return new ResponseEntity<>(HttpStatus.FOUND); + public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, + @RequestParam String authCode) { + return ResponseEntity.ok(authService.login(oAuthProvider, authCode)); } } diff --git a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java index 4cb8c8ee..76c798e3 100644 --- a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java +++ b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java @@ -2,27 +2,18 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.OAuthProvider; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; public record SignupRequest( + @NotBlank String nickname, + @NotNull List keywords, + @NotBlank String authCode, OAuthProvider oAuthProvider ) { - public static SignupRequest of( - String nickname, - List keywords, - String authCode, - OAuthProvider oAuthProvider - ) { - return new SignupRequest( - nickname, - keywords, - authCode, - oAuthProvider - ); - } - } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 5b0e7b6c..d081a8b0 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -16,7 +16,6 @@ import coffeemeet.server.user.repository.UserRepository; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -25,6 +24,7 @@ public class AuthService { private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; + private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; private final OAuthMemberClientComposite oauthMemberClientComposite; @@ -63,11 +63,14 @@ public AuthTokens signup(SignupRequest request) { return authTokensGenerator.generate(newUser.getId()); } - public Optional login(OAuthProvider oAuthProvider, String authCode) { + public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); - Optional foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()); - return foundUser.map(user -> authTokensGenerator.generate(user.getId())); + User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + response.oAuthProvider(), response.oAuthProviderId()) + .orElseThrow(() -> new IllegalArgumentException( + String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), + response.oAuthProvider()))); + return authTokensGenerator.generate(foundUser.getId()); } private void checkDuplicateUser(OAuthInfoResponse response) { From 5ad2aa239ed7aad6bc77ac1888217f0549d1783b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 18:50:11 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EA=B0=B1?= =?UTF-8?q?=EC=8B=A0=20API=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 액세스 토큰이 만료 되면, 리프레시 토큰을 통해 액세스 토큰 재발급 - 리프레시 토큰도 만료 되면 예외 발생 --- .../auth/controller/AuthController.java | 7 +++++ .../server/auth/service/AuthService.java | 31 ++++++++++--------- .../auth/utils/AuthTokensGenerator.java | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 68d96bef..a4cb4bf3 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -3,7 +3,9 @@ import coffeemeet.server.auth.dto.SignupRequest; import coffeemeet.server.auth.service.AuthService; import coffeemeet.server.auth.utils.AuthTokens; +import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.dto.AuthInfo; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import java.io.IOException; @@ -44,4 +46,9 @@ public ResponseEntity login(@PathVariable OAuthProvider oAuthProvide return ResponseEntity.ok(authService.login(oAuthProvider, authCode)); } + @PostMapping("/renew-token") + public ResponseEntity renew(@Login AuthInfo authInfo) { + return ResponseEntity.ok(authService.renew(authInfo.userId(), authInfo.refreshToken())); + } + } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index d081a8b0..d19ddf5b 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -6,6 +6,7 @@ import coffeemeet.server.auth.dto.SignupRequest; import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.auth.utils.AuthTokensGenerator; +import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; @@ -23,6 +24,7 @@ @RequiredArgsConstructor public class AuthService { + private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰이 만료되었습니다. 다시 로그인해 주세요."; private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; @@ -31,6 +33,7 @@ public class AuthService { private final UserRepository userRepository; private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; + private final JwtTokenProvider jwtTokenProvider; public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); @@ -42,19 +45,9 @@ public AuthTokens signup(SignupRequest request) { checkDuplicateUser(response); String profileImage = checkProfileImage(response.profileImage()); - User user = new User( - new OAuthInfo( - response.oAuthProvider(), - response.oAuthProviderId() - ), - Profile.builder() - .name(response.name()) - .nickname(request.nickname()) - .email(response.email()) - .profileImageUrl(profileImage) - .birth(response.birth()) - .build() - ); + User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), + Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) + .profileImageUrl(profileImage).birth(response.birth()).build()); User newUser = userRepository.save(user); @@ -66,13 +59,21 @@ public AuthTokens signup(SignupRequest request) { public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()) - .orElseThrow(() -> new IllegalArgumentException( + response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( + () -> new IllegalArgumentException( String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), response.oAuthProvider()))); return authTokensGenerator.generate(foundUser.getId()); } + public AuthTokens renew(Long userId, String refreshToken) { + if (jwtTokenProvider.isExpiredRefreshToken(refreshToken)) { + throw new IllegalArgumentException(EXPIRED_REFRESH_TOKEN_MESSAGE); + } else { + return authTokensGenerator.reissueAccessToken(userId, refreshToken); + } + } + private void checkDuplicateUser(OAuthInfoResponse response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java index 737e4f8a..f530f173 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java @@ -47,7 +47,7 @@ public AuthTokens generate(Long userId) { ); } - public AuthTokens refreshJwtToken(Long userId, String refreshToken) { + public AuthTokens reissueAccessToken(Long userId, String refreshToken) { long now = (new Date()).getTime(); Date accessTokenExpiredAt = new Date(now + accessTokenExpireTime);