From 4476541b6fd0fdd4e1b972f196ecff5de9091388 Mon Sep 17 00:00:00 2001 From: pipi-shortstocking Date: Sat, 23 Nov 2024 14:48:43 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EC=9E=AC=EB=B0=9C?= =?UTF-8?q?=EA=B8=89(#149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/security/TokenProvider.java | 17 ++--- .../mypage/controller/MypageController.java | 5 +- .../user/controller/UserController.java | 70 ++++++++++++++++++- .../user/dto/response/UserResponseDTO.java | 17 +++++ .../kw_muji/user/service/UserService.java | 5 ++ 5 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/muji_backend/kw_muji/user/dto/response/UserResponseDTO.java diff --git a/src/main/java/com/muji_backend/kw_muji/common/security/TokenProvider.java b/src/main/java/com/muji_backend/kw_muji/common/security/TokenProvider.java index 422583f5..405ddaf9 100644 --- a/src/main/java/com/muji_backend/kw_muji/common/security/TokenProvider.java +++ b/src/main/java/com/muji_backend/kw_muji/common/security/TokenProvider.java @@ -13,6 +13,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; +import java.util.Optional; @RequiredArgsConstructor @Service @@ -20,7 +21,7 @@ public class TokenProvider { private final JwtProperties jwtProperties; - public String createAccessToken(UserEntity user){ + public String createAccessToken(Optional user){ log.info("creating access token"); Date expiryDate = Date.from(Instant.now().plus(1, ChronoUnit.HOURS)); @@ -28,16 +29,16 @@ public String createAccessToken(UserEntity user){ return Jwts.builder() .signWith(SignatureAlgorithm.HS512,jwtProperties.getSecretKey()) - .setSubject(String.valueOf(user.getId())) // 토큰 제목 + .setSubject(String.valueOf(user.get().getId())) // 토큰 제목 .setIssuer(jwtProperties.getIssuer()) // 토큰 발급자 .setIssuedAt(new Date()) // 토큰 발급 시간 .setExpiration(expiryDate) // 토큰 만료 시간 - .claim("id", user.getId()) // 토큰에 사용자 아이디 추가하여 전달 - .claim("email", user.getEmail()) + .claim("id", user.get().getId()) // 토큰에 사용자 아이디 추가하여 전달 + .claim("email", user.get().getEmail()) .compact(); // 토큰 생성 } - public String createRefreshToken(UserEntity user){ + public String createRefreshToken(Optional user){ log.info("creating refresh token"); Date expiryDate = Date.from(Instant.now().plus(1, ChronoUnit.DAYS)); @@ -45,12 +46,12 @@ public String createRefreshToken(UserEntity user){ return Jwts.builder() .signWith(SignatureAlgorithm.HS512,jwtProperties.getSecretKey()) - .setSubject(String.valueOf(user.getId())) + .setSubject(String.valueOf(user.get().getId())) .setIssuer(jwtProperties.getIssuer()) .setIssuedAt(new Date()) .setExpiration(expiryDate) - .claim("id", user.getId()) - .claim("email", user.getEmail()) + .claim("id", user.get().getId()) + .claim("email", user.get().getEmail()) .compact(); } diff --git a/src/main/java/com/muji_backend/kw_muji/mypage/controller/MypageController.java b/src/main/java/com/muji_backend/kw_muji/mypage/controller/MypageController.java index 68b116f0..49a21014 100644 --- a/src/main/java/com/muji_backend/kw_muji/mypage/controller/MypageController.java +++ b/src/main/java/com/muji_backend/kw_muji/mypage/controller/MypageController.java @@ -28,6 +28,7 @@ import java.net.URLEncoder; import java.util.List; import java.util.Map; +import java.util.Optional; @RestController @RequiredArgsConstructor @@ -104,8 +105,8 @@ else if (dto.isDeleteImage()) // 프로필 사진 삭제를 요청한 경우 final UserEntity updateUser = mypageService.updateUser(userInfo, dto); final TokenDTO resDTO = TokenDTO.builder() - .accessToken(tokenProvider.createAccessToken(updateUser)) - .refreshToken(tokenProvider.createRefreshToken(updateUser)) + .accessToken(tokenProvider.createAccessToken(Optional.ofNullable(updateUser))) + .refreshToken(tokenProvider.createRefreshToken(Optional.ofNullable(updateUser))) .build(); return ResponseEntity.ok().body(Map.of("code", 200, "data", resDTO)); diff --git a/src/main/java/com/muji_backend/kw_muji/user/controller/UserController.java b/src/main/java/com/muji_backend/kw_muji/user/controller/UserController.java index 48ca57ea..8c9e4846 100644 --- a/src/main/java/com/muji_backend/kw_muji/user/controller/UserController.java +++ b/src/main/java/com/muji_backend/kw_muji/user/controller/UserController.java @@ -1,14 +1,20 @@ package com.muji_backend.kw_muji.user.controller; +import com.muji_backend.kw_muji.common.config.jwt.JwtProperties; import com.muji_backend.kw_muji.common.entity.UserEntity; import com.muji_backend.kw_muji.common.entity.enums.UserRole; import com.muji_backend.kw_muji.common.security.TokenProvider; import com.muji_backend.kw_muji.user.dto.request.*; import com.muji_backend.kw_muji.user.dto.response.TokenDTO; +import com.muji_backend.kw_muji.user.dto.response.UserResponseDTO; import com.muji_backend.kw_muji.user.service.MailSendService; import com.muji_backend.kw_muji.user.service.RedisService; import com.muji_backend.kw_muji.user.service.UserService; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; @@ -22,6 +28,8 @@ import org.springframework.web.bind.annotation.RestController; import java.util.Map; +import java.util.Optional; +import java.util.UUID; @RestController @RequiredArgsConstructor @@ -32,6 +40,7 @@ public class UserController { private final UserService userService; private final RedisService redisService; private final TokenProvider tokenProvider; + private final JwtProperties jwtProperties; private final PasswordEncoder pwEncoder = new BCryptPasswordEncoder(); @@ -108,6 +117,7 @@ public ResponseEntity> authCheck(@RequestBody @Valid AuthNum return ResponseEntity.status(500).body(Map.of("code", 500, "data", "인증번호 확인 오류. 잠시 후 다시 시도해주세요.")); } } + @PostMapping("/signIn") public ResponseEntity> signIn(@RequestBody @Valid SignInRequestDTO dto, BindingResult bindingResult) { try { @@ -119,8 +129,8 @@ public ResponseEntity> signIn(@RequestBody @Valid SignInRequ throw new IllegalArgumentException("로그인 실패"); } - final String accessToken = tokenProvider.createAccessToken(user); - final String refreshToken = tokenProvider.createRefreshToken(user); + final String accessToken = tokenProvider.createAccessToken(Optional.of(user)); + final String refreshToken = tokenProvider.createRefreshToken(Optional.of(user)); final TokenDTO resDTO = TokenDTO.builder() .accessToken(accessToken) @@ -172,4 +182,60 @@ public ResponseEntity> resetPassword(@RequestBody @Valid Res return ResponseEntity.status(500).body(Map.of("code", 500, "data", "비밀번호 재설정 오류. 잠시 후 다시 시도해주세요.")); } } + + // accessToken 재발급 + @PostMapping("/newToken") + public ResponseEntity createNewToken(HttpServletRequest request){ + try { + String token = request.getHeader("Authorization").substring(7); + log.info("create new accessToken from : {}", token); + + Claims claims = Jwts.parser() + .setSigningKey(jwtProperties.getSecretKey()) + .parseClaimsJws(token) + .getBody(); + + Long id = Long.parseLong(claims.getSubject()); + + Optional user = userService.getById(id); + final UserResponseDTO resUserDTO = UserResponseDTO.builder() + .id(user.get().getId()) + .email(user.get().getEmail()) + .accessToken(tokenProvider.createAccessToken(user)) + .build(); + + return ResponseEntity.ok().body(resUserDTO); + }catch (Exception e){ + log.error("/auth/newToken 실행 중 예외 발생", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("newToken fail"); + } + } + + // refreshToken 재발급 + @PostMapping("/newRefreshToken") + public ResponseEntity createNewRefreshToken(HttpServletRequest request){ + try { + String token = request.getHeader("Authorization").substring(7); + log.info("create new refresh Token from : {}", token); + + Claims claims = Jwts.parser() + .setSigningKey(jwtProperties.getSecretKey()) + .parseClaimsJws(token) + .getBody(); + + Long id = Long.parseLong(claims.getSubject()); + + Optional user = userService.getById(id); + final UserResponseDTO resUserDTO = UserResponseDTO.builder() + .id(user.get().getId()) + .email(user.get().getEmail()) + .refreshToken(tokenProvider.createRefreshToken(user)) + .build(); + + return ResponseEntity.ok().body(resUserDTO); + }catch (Exception e){ + log.error("/auth/newrefreshToken 실행 중 예외 발생", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("newRefreshToken fail"); + } + } } diff --git a/src/main/java/com/muji_backend/kw_muji/user/dto/response/UserResponseDTO.java b/src/main/java/com/muji_backend/kw_muji/user/dto/response/UserResponseDTO.java new file mode 100644 index 00000000..5aa03a2d --- /dev/null +++ b/src/main/java/com/muji_backend/kw_muji/user/dto/response/UserResponseDTO.java @@ -0,0 +1,17 @@ +package com.muji_backend.kw_muji.user.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UserResponseDTO { + private long id; + private String email; + private String accessToken; + private String refreshToken; +} diff --git a/src/main/java/com/muji_backend/kw_muji/user/service/UserService.java b/src/main/java/com/muji_backend/kw_muji/user/service/UserService.java index 19b4dcbe..a00a3b2a 100644 --- a/src/main/java/com/muji_backend/kw_muji/user/service/UserService.java +++ b/src/main/java/com/muji_backend/kw_muji/user/service/UserService.java @@ -9,6 +9,7 @@ import org.springframework.validation.BindingResult; import java.util.Objects; +import java.util.Optional; @RequiredArgsConstructor @Slf4j @@ -53,4 +54,8 @@ public void updatePw(final String email, final UserEntity user) { userRepo.save(updateUser); } + + public Optional getById(final Long id) { + return userRepo.findById(id); + } }