From 77d506d15bc7d59ae9c3c091d3402528932ee838 Mon Sep 17 00:00:00 2001 From: NameIsUser06 Date: Tue, 19 Dec 2023 23:18:26 +0900 Subject: [PATCH] feat : Token Refresh --- .../auth/exception/BadRequestException.java | 11 +++++ .../RefreshTokenNotFoundException.java | 11 +++++ .../auth/presentation/AuthController.java | 9 ++++ .../auth/service/RefreshTokenService.java | 48 +++++++++++++++++++ .../auth/service/SaveRefreshTokenService.java | 6 +-- .../auth/service/UserSignUpService.java | 40 ++++++++-------- .../global/error/exception/ErrorCode.java | 4 +- .../global/jwt/util/JwtProvider.java | 12 ++--- .../findfriend/global/jwt/util/JwtUtil.java | 4 +- 9 files changed, 110 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/investment/findfriend/domain/auth/exception/BadRequestException.java create mode 100644 src/main/java/com/investment/findfriend/domain/auth/exception/RefreshTokenNotFoundException.java create mode 100644 src/main/java/com/investment/findfriend/domain/auth/service/RefreshTokenService.java diff --git a/src/main/java/com/investment/findfriend/domain/auth/exception/BadRequestException.java b/src/main/java/com/investment/findfriend/domain/auth/exception/BadRequestException.java new file mode 100644 index 0000000..f75b73c --- /dev/null +++ b/src/main/java/com/investment/findfriend/domain/auth/exception/BadRequestException.java @@ -0,0 +1,11 @@ +package com.investment.findfriend.domain.auth.exception; + +import com.investment.findfriend.global.error.exception.ErrorCode; +import com.investment.findfriend.global.error.exception.FindFriendException; + +public class BadRequestException extends FindFriendException { + public static final BadRequestException EXCEPTION = new BadRequestException(ErrorCode.BAD_REQUEST); + public BadRequestException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/com/investment/findfriend/domain/auth/exception/RefreshTokenNotFoundException.java b/src/main/java/com/investment/findfriend/domain/auth/exception/RefreshTokenNotFoundException.java new file mode 100644 index 0000000..472eb66 --- /dev/null +++ b/src/main/java/com/investment/findfriend/domain/auth/exception/RefreshTokenNotFoundException.java @@ -0,0 +1,11 @@ +package com.investment.findfriend.domain.auth.exception; + +import com.investment.findfriend.global.error.exception.ErrorCode; +import com.investment.findfriend.global.error.exception.FindFriendException; + +public class RefreshTokenNotFoundException extends FindFriendException { + public static final RefreshTokenNotFoundException EXCEPTION = new RefreshTokenNotFoundException(ErrorCode.REFRESH_TOKEN_NOT_FOUND); + public RefreshTokenNotFoundException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/com/investment/findfriend/domain/auth/presentation/AuthController.java b/src/main/java/com/investment/findfriend/domain/auth/presentation/AuthController.java index 94284d5..3de3d0a 100644 --- a/src/main/java/com/investment/findfriend/domain/auth/presentation/AuthController.java +++ b/src/main/java/com/investment/findfriend/domain/auth/presentation/AuthController.java @@ -2,7 +2,10 @@ import com.investment.findfriend.domain.auth.domain.Auth; import com.investment.findfriend.domain.auth.presentation.dto.response.TokenResponse; +import com.investment.findfriend.domain.auth.service.RefreshTokenService; +import com.investment.findfriend.domain.auth.service.SaveRefreshTokenService; import com.investment.findfriend.domain.auth.service.UserSignUpService; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -13,10 +16,16 @@ public class AuthController { private final UserSignUpService userSignUpService; + private final RefreshTokenService refreshTokenService; @PostMapping("/signup") public ResponseEntity signUp(@RequestParam("code") String code, @RequestParam("auth")Auth auth) { return userSignUpService.execute(code, auth); } + @PutMapping("/refresh") + public ResponseEntity refresh(HttpServletRequest request) { + return refreshTokenService.execute(request); + } + } diff --git a/src/main/java/com/investment/findfriend/domain/auth/service/RefreshTokenService.java b/src/main/java/com/investment/findfriend/domain/auth/service/RefreshTokenService.java new file mode 100644 index 0000000..3e8d913 --- /dev/null +++ b/src/main/java/com/investment/findfriend/domain/auth/service/RefreshTokenService.java @@ -0,0 +1,48 @@ +package com.investment.findfriend.domain.auth.service; + +import com.investment.findfriend.domain.auth.domain.RefreshToken; +import com.investment.findfriend.domain.auth.exception.BadRequestException; +import com.investment.findfriend.domain.auth.exception.RefreshTokenNotFoundException; +import com.investment.findfriend.domain.auth.presentation.dto.response.TokenResponse; +import com.investment.findfriend.domain.auth.repository.RefreshTokenRepository; +import com.investment.findfriend.global.jwt.util.JwtProvider; +import com.investment.findfriend.global.jwt.util.JwtUtil; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class RefreshTokenService { + + private final JwtUtil jwtUtil; + private final JwtProvider jwtProvider; + private final RefreshTokenRepository refreshTokenRepository; + + @Transactional + public ResponseEntity execute(HttpServletRequest request) { + try { + String email = jwtUtil.extractEmailByToken( + request.getHeader("Authorization-refresh").split(" ")[1].trim() + ); + + RefreshToken refreshToken = refreshTokenRepository.findByEmail(email).orElseThrow( + () -> RefreshTokenNotFoundException.EXCEPTION + ); + String newAccessToken = jwtProvider.createAccessToken(email); + String newRefreshToken = jwtProvider.createRefreshToken(email); + refreshToken.setToken(newAccessToken, newRefreshToken); + refreshTokenRepository.save(refreshToken); + return ResponseEntity.ok(TokenResponse.builder() + .accessToken(newAccessToken) + .refreshToken(newRefreshToken) + .build()); + } catch (NullPointerException e) { + throw BadRequestException.EXCEPTION; + } + } +} diff --git a/src/main/java/com/investment/findfriend/domain/auth/service/SaveRefreshTokenService.java b/src/main/java/com/investment/findfriend/domain/auth/service/SaveRefreshTokenService.java index 9cc2c2c..e9d6ea5 100644 --- a/src/main/java/com/investment/findfriend/domain/auth/service/SaveRefreshTokenService.java +++ b/src/main/java/com/investment/findfriend/domain/auth/service/SaveRefreshTokenService.java @@ -18,9 +18,9 @@ public class SaveRefreshTokenService { private final RefreshTokenRepository refreshTokenRepository; private final JwtProvider jwtProvider; - public ResponseEntity execute(String email, Authority authority) { - String accessToken = jwtProvider.createAccessToken(email, authority); - String refreshToken = jwtProvider.createRefreshToken(email, authority); + public ResponseEntity execute(String email) { + String accessToken = jwtProvider.createAccessToken(email); + String refreshToken = jwtProvider.createRefreshToken(email); Optional refresh_token = refreshTokenRepository.findByEmail(email); diff --git a/src/main/java/com/investment/findfriend/domain/auth/service/UserSignUpService.java b/src/main/java/com/investment/findfriend/domain/auth/service/UserSignUpService.java index 3e505e3..a20d579 100644 --- a/src/main/java/com/investment/findfriend/domain/auth/service/UserSignUpService.java +++ b/src/main/java/com/investment/findfriend/domain/auth/service/UserSignUpService.java @@ -48,18 +48,17 @@ public ResponseEntity execute(String code, Auth auth) { googleTokenResponse.getAccess_token() ); - User user = User.builder() - .name(googleUserInfoResponse.getName()) - .authority(Authority.ROLE_USER) - .email(googleUserInfoResponse.getEmail()) - .statusMessage("상태 메시지") - .build(); - if (userRepository.findByEmail(googleUserInfoResponse.getEmail()).isEmpty()) { - userRepository.save(user); + userRepository.save( + User.builder() + .name(googleUserInfoResponse.getName()) + .authority(Authority.ROLE_USER) + .email(googleUserInfoResponse.getEmail()) + .statusMessage("상태 메시지") + .build()); } - return saveRefreshTokenService.execute(googleUserInfoResponse.getEmail(), user.getAuthority()); + return saveRefreshTokenService.execute(googleUserInfoResponse.getEmail()); } else if (auth == Auth.NAVER) { NaverTokenResponse naverTokenResponse = naverGetTokenClient.execute( code, @@ -72,20 +71,19 @@ public ResponseEntity execute(String code, Auth auth) { naverTokenResponse.getToken_type() + " " + naverTokenResponse.getAccess_token() ).getResponse(); - User user = User.builder() - .name(naverUserInfoResponse.getName()) - .email(naverUserInfoResponse.getEmail()) - .gender(naverUserInfoResponse.getGender().equals("M") ? Gender.MALE : Gender.FEMALE) - .authority(Authority.ROLE_USER) - .birthdate(LocalDate.parse(naverUserInfoResponse.getBirthyear() + "-" + naverUserInfoResponse.getBirthday())) - .phone(naverUserInfoResponse.getMobile()) - .statusMessage("상태 메시지") - .build(); - if (userRepository.findByEmail(naverUserInfoResponse.getEmail()).isEmpty()) { - userRepository.save(user); + userRepository.save( + User.builder() + .name(naverUserInfoResponse.getName()) + .email(naverUserInfoResponse.getEmail()) + .gender(naverUserInfoResponse.getGender().equals("M") ? Gender.MALE : Gender.FEMALE) + .authority(Authority.ROLE_USER) + .birthdate(LocalDate.parse(naverUserInfoResponse.getBirthyear() + "-" + naverUserInfoResponse.getBirthday())) + .phone(naverUserInfoResponse.getMobile()) + .statusMessage("상태 메시지") + .build()); } - return saveRefreshTokenService.execute(naverUserInfoResponse.getEmail(), user.getAuthority()); + return saveRefreshTokenService.execute(naverUserInfoResponse.getEmail()); } return null; } diff --git a/src/main/java/com/investment/findfriend/global/error/exception/ErrorCode.java b/src/main/java/com/investment/findfriend/global/error/exception/ErrorCode.java index d9f960f..184d1c0 100644 --- a/src/main/java/com/investment/findfriend/global/error/exception/ErrorCode.java +++ b/src/main/java/com/investment/findfriend/global/error/exception/ErrorCode.java @@ -11,7 +11,9 @@ public enum ErrorCode { USER_NOT_FOUND(404, "유저를 찾을 수 없습니다"), LOGGED_OUT_TOKEN(403, "로그아웃 되어 사용할 수 없는 토큰입니다"), TOKEN_NOT_FOUND(404, "토큰이 존재하지 않습니다"), - FRIEND_NOT_FOUND(404, "친구를 찾을 수 없습니다"); + REFRESH_TOKEN_NOT_FOUND(404, "토큰이 DB에 존재하지 않습니다"), + FRIEND_NOT_FOUND(404, "친구를 찾을 수 없습니다"), + BAD_REQUEST(400, "잘못된 요청입니다"); private final int status; private final String message; diff --git a/src/main/java/com/investment/findfriend/global/jwt/util/JwtProvider.java b/src/main/java/com/investment/findfriend/global/jwt/util/JwtProvider.java index 42d5db5..b92c4cc 100644 --- a/src/main/java/com/investment/findfriend/global/jwt/util/JwtProvider.java +++ b/src/main/java/com/investment/findfriend/global/jwt/util/JwtProvider.java @@ -1,6 +1,5 @@ package com.investment.findfriend.global.jwt.util; -import com.investment.findfriend.domain.user.domain.type.Authority; import com.investment.findfriend.global.jwt.properties.JwtProperties; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @@ -15,19 +14,18 @@ public class JwtProvider { private final JwtProperties jwtProperties; - public String createAccessToken(String email, Authority authority) { - return createToken(email, authority, jwtProperties.getAccessExp()); + public String createAccessToken(String email) { + return createToken(email, jwtProperties.getAccessExp()); } - public String createRefreshToken(String email, Authority authority) { - return createToken(email, authority, jwtProperties.getRefreshExp()); + public String createRefreshToken(String email) { + return createToken(email, jwtProperties.getRefreshExp()); } - private String createToken(String email, Authority authority, long expirationTime) { + private String createToken(String email, long expirationTime) { Date now = new Date(); return Jwts.builder() .setSubject(email) - .claim("AUTHORIZATION_KEY", authority) .signWith(jwtProperties.getSecret(), SignatureAlgorithm.HS256) .setExpiration(new Date(now.getTime() + expirationTime)) .compact(); diff --git a/src/main/java/com/investment/findfriend/global/jwt/util/JwtUtil.java b/src/main/java/com/investment/findfriend/global/jwt/util/JwtUtil.java index 44c70b9..b6c251e 100644 --- a/src/main/java/com/investment/findfriend/global/jwt/util/JwtUtil.java +++ b/src/main/java/com/investment/findfriend/global/jwt/util/JwtUtil.java @@ -1,11 +1,9 @@ package com.investment.findfriend.global.jwt.util; -import com.investment.findfriend.global.jwt.exception.LoggedOutAccessTokenException; import com.investment.findfriend.global.jwt.exception.TokenNotFoundException; import com.investment.findfriend.global.jwt.properties.JwtProperties; import com.investment.findfriend.global.security.auth.AuthDetails; import com.investment.findfriend.global.security.auth.AuthDetailsService; -import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @@ -34,7 +32,7 @@ public Authentication getAuthentication(String token) { return new UsernamePasswordAuthenticationToken(authDetails, token, authDetails.getAuthorities()); } - private String extractEmailByToken(String token) { + public String extractEmailByToken(String token) { return Jwts.parserBuilder() .setSigningKey(jwtProperties.getSecret()) .build()