diff --git a/.gitignore b/.gitignore index 4a684a41..2b06d3f7 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,5 @@ out/ src/main/resources/application.yml ### jacoco ### -jacoco \ No newline at end of file +jacoco +src/main/java/com/example/ApiClient.java diff --git a/src/main/java/com/example/spot/api/code/status/ErrorStatus.java b/src/main/java/com/example/spot/api/code/status/ErrorStatus.java index 77a337f4..37862f98 100644 --- a/src/main/java/com/example/spot/api/code/status/ErrorStatus.java +++ b/src/main/java/com/example/spot/api/code/status/ErrorStatus.java @@ -27,6 +27,7 @@ public enum ErrorStatus implements BaseErrorCode { _VALUE_RANGE_EXCEEDED(HttpStatus.BAD_REQUEST, "COMMON4012", "값이 지정된 범위를 초과합니다."), _TERMS_NOT_AGREED(HttpStatus.FORBIDDEN, "COMMON4013", "이용 약관이 동의되지 않았습니다."), _MEMBER_EMAIL_EXIST(HttpStatus.BAD_REQUEST, "COMMON4014", "이미 가입 된 이메일입니다. 다른 로그인 방식을 이용해주세요."), + _RSA_ERROR(HttpStatus.BAD_REQUEST, "COMMON4015", "RSA 에러가 발생했습니다."), // 네이버 소셜 로그인 관련 에러 _NAVER_SIGN_IN_INTEGRATION_FAILED(HttpStatus.UNAUTHORIZED, "NAVER4001", "네이버 로그인 연동에 실패하였습니다."), diff --git a/src/main/java/com/example/spot/api/code/status/SuccessStatus.java b/src/main/java/com/example/spot/api/code/status/SuccessStatus.java index 61e27953..b606afd3 100644 --- a/src/main/java/com/example/spot/api/code/status/SuccessStatus.java +++ b/src/main/java/com/example/spot/api/code/status/SuccessStatus.java @@ -30,6 +30,7 @@ public enum SuccessStatus implements BaseCode { _MEMBER_LOGIN_ID_FOUND(HttpStatus.OK, "MEMBER2012", "회원 아이디 조회 완료"), _MEMBER_LOGIN_ID_CHECK_COMPLETED(HttpStatus.OK, "MEMBER2012", "회원 아이디 사용 가능 여부 조회 완료"), _MEMBER_EMAIL_CHECK_COMPLETED(HttpStatus.OK, "MEMBER2013", "회원 이메일 사용 가능 여부 조회 완료"), + _RSA_PUBLIC_KEY_FOUND(HttpStatus.OK, "MEMBER2014", "RSA Public Key 조회 완료"), //스터디 게시글 관련 응답 _STUDY_POST_CREATED(HttpStatus.CREATED, "STUDYPOST3001", "스터디 게시글 작성 완료"), diff --git a/src/main/java/com/example/spot/config/WebSecurity.java b/src/main/java/com/example/spot/config/WebSecurity.java index 2f6c76fa..0c9956e2 100644 --- a/src/main/java/com/example/spot/config/WebSecurity.java +++ b/src/main/java/com/example/spot/config/WebSecurity.java @@ -55,6 +55,7 @@ protected SecurityFilterChain configure(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher("/spot/reissue")).permitAll() .requestMatchers(new AntPathRequestMatcher("/spot/sign-up", "POST")).permitAll() .requestMatchers(new AntPathRequestMatcher("/spot/login", "POST")).permitAll() + .requestMatchers(new AntPathRequestMatcher("/spot/login/rsa", "POST")).permitAll() .requestMatchers(new AntPathRequestMatcher("/spot/members/sign-in/naver", "POST")).permitAll() .requestMatchers(new AntPathRequestMatcher("/spot/members/sign-in/naver/redirect", "GET")).permitAll() .requestMatchers(new AntPathRequestMatcher("/spot/members/sign-in/naver/authorize/test", "GET")).permitAll() diff --git a/src/main/java/com/example/spot/domain/auth/RsaKey.java b/src/main/java/com/example/spot/domain/auth/RsaKey.java new file mode 100644 index 00000000..5736b390 --- /dev/null +++ b/src/main/java/com/example/spot/domain/auth/RsaKey.java @@ -0,0 +1,30 @@ +package com.example.spot.domain.auth; + +import com.example.spot.domain.common.BaseEntity; +import jakarta.persistence.*; +import lombok.*; + +@Getter +@Entity +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class RsaKey extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, unique = true) + private Long id; + + @Column(columnDefinition = "text") + private String privateKey; + + @Column(columnDefinition = "text") + private String publicKey; + + @Column(columnDefinition = "text") + private String modulus; + + @Column(columnDefinition = "text") + private String exponent; +} diff --git a/src/main/java/com/example/spot/repository/rsa/RSAKeyRepository.java b/src/main/java/com/example/spot/repository/rsa/RSAKeyRepository.java new file mode 100644 index 00000000..6f31d0d9 --- /dev/null +++ b/src/main/java/com/example/spot/repository/rsa/RSAKeyRepository.java @@ -0,0 +1,13 @@ +package com.example.spot.repository.rsa; + +import com.example.spot.domain.auth.RsaKey; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.time.LocalDateTime; + +@Repository +public interface RSAKeyRepository extends JpaRepository { + + void deleteByCreatedAtBefore(LocalDateTime localDateTime); +} diff --git a/src/main/java/com/example/spot/security/utils/RSAUtils.java b/src/main/java/com/example/spot/security/utils/RSAUtils.java new file mode 100644 index 00000000..04f96451 --- /dev/null +++ b/src/main/java/com/example/spot/security/utils/RSAUtils.java @@ -0,0 +1,134 @@ +package com.example.spot.security.utils; + +import com.example.spot.api.code.status.ErrorStatus; +import com.example.spot.api.exception.handler.MemberHandler; +import com.example.spot.domain.auth.RsaKey; +import org.springframework.stereotype.Component; + +import javax.crypto.Cipher; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.util.Base64; + +@Component +public class RSAUtils { + + private final KeyPairGenerator generator; + private final KeyFactory keyFactory; + private final Cipher cipher; + + public RSAUtils() throws Exception { + SecureRandom secureRandom = new SecureRandom(); + generator = KeyPairGenerator.getInstance("RSA"); + generator.initialize(2048, secureRandom); + keyFactory = KeyFactory.getInstance("RSA"); + cipher = Cipher.getInstance("RSA"); + } + + /** + * RSA Public Key와 Private Key를 생성하는 함수 + * @return 생성된 RSA 객체 + */ + public RsaKey createRSA() { + + try { + // Key Pair 생성 + KeyPair keyPair = generator.generateKeyPair(); + PublicKey publicKey = keyPair.getPublic(); + PrivateKey privateKey = keyPair.getPrivate(); + + RSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class); + String modulus = publicKeySpec.getModulus().toString(16); // 16진수 문자열 + String exponent = publicKeySpec.getPublicExponent().toString(16); // 16진수 문자열 + + return RsaKey.builder() + .publicKey(getBase64StringFromPublicKey(publicKey)) + .privateKey(getBase64StringFromPrivateKey(privateKey)) + .modulus(modulus) + .exponent(exponent) + .build(); + + } catch (Exception e) { + e.printStackTrace(); + throw new MemberHandler(ErrorStatus._RSA_ERROR); + } + + } + + /** + * Public Key를 Base64 문자열로 변환하는 함수 + * @param publicKey : 암호화에 사용될 publicKey + * @return Public Key를 Base64 문자열로 변환한 값 + */ + public String getBase64StringFromPublicKey(PublicKey publicKey) { + return Base64.getEncoder().encodeToString(publicKey.getEncoded()); + } + + /** + * Private Key를 Base64 문자열로 변환하는 함수 + * @param privateKey : 암호화에 사용될 privateKey + * @return Public Key를 Base64 문자열로 변환한 값 + */ + public String getBase64StringFromPrivateKey(PrivateKey privateKey) { + return Base64.getEncoder().encodeToString(privateKey.getEncoded()); + } + + /** + * Base64 문자열을 PrivateKey 객체로 변환하는 함수 + * @param privateKeyString :Private Key를 Base64 문자열로 변환한 값 + * @return PrivateKey 객체 + */ + public PrivateKey getPrivateKeyFromBase64String(String privateKeyString) { + + try { + // Base64 디코딩 + byte[] keyBytes = Base64.getDecoder().decode(privateKeyString); + + // PrivateKey 객체 생성 + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(keySpec); + } catch (Exception e) { + e.printStackTrace(); + throw new MemberHandler(ErrorStatus._RSA_ERROR); + } + + } + + /** + * Public Key로 문자열을 암호화하는 함수 + * @param publicKey : 암호화에 사용될 publicKey + * @param plainText : 암호화되지 않은 문자열 + * @return 암호화된 문자열 + */ + public String getEncryptedText(PublicKey publicKey, String plainText) { + try { + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] plainBytes = cipher.doFinal(plainText.getBytes()); + return Base64.getEncoder().encodeToString(plainBytes); + } catch (Exception e) { + e.printStackTrace(); + throw new MemberHandler(ErrorStatus._RSA_ERROR); + } + } + + /** + * Private Key로 문자열을 복호화하는 함수 + * @param privateKey : 복호화에 사용될 privateKey + * @param encryptedText : 암호화된 문자열 + * @return 복호화된 문자열 + */ + public String getDecryptedText(PrivateKey privateKey, String encryptedText) { + try { + byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] plainBytes = cipher.doFinal(encryptedBytes); + return new String(plainBytes, StandardCharsets.UTF_8); + } catch (Exception e) { + e.printStackTrace(); + throw new MemberHandler(ErrorStatus._RSA_ERROR); + } + } +} diff --git a/src/main/java/com/example/spot/service/auth/AuthService.java b/src/main/java/com/example/spot/service/auth/AuthService.java index 02f2bc9f..57539b1e 100644 --- a/src/main/java/com/example/spot/service/auth/AuthService.java +++ b/src/main/java/com/example/spot/service/auth/AuthService.java @@ -1,5 +1,6 @@ package com.example.spot.service.auth; +import com.example.spot.web.dto.rsa.Rsa; import com.example.spot.web.dto.member.MemberRequestDTO; import com.example.spot.web.dto.member.MemberResponseDTO; import com.example.spot.web.dto.member.MemberResponseDTO.SocialLoginSignInDTO; @@ -23,13 +24,15 @@ public interface AuthService { SocialLoginSignInDTO signInWithNaver(HttpServletRequest request, HttpServletResponse response, NaverOAuthToken.NaverTokenIssuanceDTO naverTokenDTO) throws Exception; - MemberResponseDTO.MemberSignInDTO signIn(MemberRequestDTO.SignInDTO signInDTO); + MemberResponseDTO.MemberSignInDTO signIn(Long httpSession, MemberRequestDTO.SignInDTO signInDTO) throws Exception; + + Rsa.RSAPublicKey getRSAPublicKey() throws Exception; void sendVerificationCode(HttpServletRequest request, HttpServletResponse response, String email); TokenResponseDTO.TempTokenDTO verifyEmail(String verificationCode, String email); - MemberResponseDTO.MemberSignInDTO signUp(MemberRequestDTO.SignUpDTO signUpDTO); + MemberResponseDTO.MemberSignInDTO signUp(Long rsaId, MemberRequestDTO.SignUpDTO signUpDTO) throws Exception; MemberResponseDTO.FindIdDTO findId(); diff --git a/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java b/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java index 7bb30ab1..b043e1d0 100644 --- a/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java +++ b/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java @@ -5,6 +5,8 @@ import com.example.spot.api.exception.GeneralException; import com.example.spot.api.exception.handler.MemberHandler; import com.example.spot.domain.Member; +import com.example.spot.domain.auth.RsaKey; +import com.example.spot.web.dto.rsa.Rsa; import com.example.spot.domain.auth.RefreshToken; import com.example.spot.domain.auth.VerificationCode; import com.example.spot.domain.enums.Carrier; @@ -13,9 +15,11 @@ import com.example.spot.domain.enums.Status; import com.example.spot.repository.MemberRepository; import com.example.spot.repository.RefreshTokenRepository; +import com.example.spot.repository.rsa.RSAKeyRepository; import com.example.spot.repository.verification.VerificationCodeRepository; import com.example.spot.security.utils.JwtTokenProvider; import com.example.spot.security.utils.MemberUtils; +import com.example.spot.security.utils.RSAUtils; import com.example.spot.web.dto.member.MemberRequestDTO; import com.example.spot.web.dto.member.MemberResponseDTO; import com.example.spot.security.utils.SecurityUtils; @@ -27,8 +31,10 @@ import com.example.spot.web.dto.token.TokenResponseDTO; import com.example.spot.web.dto.token.TokenResponseDTO.TokenDTO; +import java.security.PrivateKey; import java.security.SecureRandom; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Objects; import java.util.Random; @@ -56,6 +62,9 @@ public class AuthServiceImpl implements AuthService{ private final MailService mailService; private final NaverOAuthService naverOAuthService; + private final RSAUtils rsaUtils; + private final RSAKeyRepository rsaKeyRepository; + @Value("${image.post.anonymous.profile}") private String DEFAULT_PROFILE_IMAGE_URL; @@ -258,18 +267,19 @@ private void signUpWithNaver(NaverMember.ResponseDTO memberDTO) { /** * 일반 로그인을 위한 메서드입니다. 아이디와 비밀번호를 확인한 후 토큰을 발급하는 로직을 수행합니다. - * @param signInDTO 로그인할 회원의 아이디와 비밀번호를 입력 받습니다. + * @param signInDTO 로그인할 회원의 아이디와 비밀번호를 입력 받습니다. * @return 로그인한 회원의 토큰 정보(액세스 & 리프레시 토큰 & 만료기간), 이메일과 회원 아이디(정수)가 반환됩니다. */ @Override - public MemberResponseDTO.MemberSignInDTO signIn(MemberRequestDTO.SignInDTO signInDTO) { + public MemberResponseDTO.MemberSignInDTO signIn(Long rsaId, MemberRequestDTO.SignInDTO signInDTO) throws Exception { // 아이디가 일치하는 유저가 있는지 확인 Member member = memberRepository.findByLoginId(signInDTO.getLoginId()) .orElseThrow(() -> new MemberHandler(ErrorStatus._MEMBER_NOT_FOUND)); // 비밀번호 확인 - if (!signInDTO.getPassword().equals(member.getPassword())) { + String password = getDecryptedPassword(rsaId, signInDTO.getPassword()); + if (!password.equals(member.getPassword())) { throw new MemberHandler(ErrorStatus._MEMBER_PASSWORD_NOT_MATCH); } @@ -285,6 +295,33 @@ public MemberResponseDTO.MemberSignInDTO signIn(MemberRequestDTO.SignInDTO signI .build(); } + private String getDecryptedPassword(Long rsaId, String encryptedPassword) throws Exception { + + // Private Key 추출 후 Session에 저장된 Private Key 초기화 + RsaKey rsaKey = rsaKeyRepository.findById(rsaId) + .orElseThrow(() -> new MemberHandler(ErrorStatus._RSA_ERROR)); + rsaKeyRepository.deleteByCreatedAtBefore(LocalDateTime.now().minusMinutes(1)); + + // 복호화된 패스워드 반환 + PrivateKey privateKey = rsaUtils.getPrivateKeyFromBase64String(rsaKey.getPrivateKey()); + return rsaUtils.getDecryptedText(privateKey, encryptedPassword); + } + + @Override + public Rsa.RSAPublicKey getRSAPublicKey() throws Exception { + + // RSA 생성 + RsaKey rsa = rsaUtils.createRSA(); + rsa = rsaKeyRepository.save(rsa); + + // Public Key 반환 + return Rsa.RSAPublicKey.builder() + .rsaId(rsa.getId()) + .modulus(rsa.getModulus()) + .exponent(rsa.getExponent()) + .build(); + } + /** * 인증 코드를 전송하는 메서드입니다. * 일반 회원가입, 아이디 찾기, 비밀번호 찾기에 공통으로 적용되는 인증 메일 전송 로직입니다. @@ -344,18 +381,20 @@ public TokenResponseDTO.TempTokenDTO verifyEmail(String code, String email) { /** * 일반 회원가입에 사용되는 메서드입니다. + * + * @param rsaId * @param signUpDTO 회원의 기본 정보를 입력 받습니다. * name : 이름 * frontRID : 주민번호 앞자리 * backRID : 주민번호 뒷자리 첫 글자 * email : 이메일 * loginId : 아이디 - * password : 비밀번호 + * password : 비밀번호 (RSA Key로 암호화한 값) * pwCheck : 비밀번호 확인 * @return 가입한 회원은 자동으로 로그인되며, 회원의 토큰 정보(액세스 & 리프레시 토큰 & 만료기간), 이메일과 회원 아이디(정수)가 반환됩니다. */ @Override - public MemberResponseDTO.MemberSignInDTO signUp(MemberRequestDTO.SignUpDTO signUpDTO) { + public MemberResponseDTO.MemberSignInDTO signUp(Long rsaId, MemberRequestDTO.SignUpDTO signUpDTO) throws Exception { // 회원 생성 if (memberRepository.existsByEmail(signUpDTO.getEmail())) { @@ -364,7 +403,10 @@ public MemberResponseDTO.MemberSignInDTO signUp(MemberRequestDTO.SignUpDTO signU if (memberRepository.existsByLoginId(signUpDTO.getLoginId())) { throw new MemberHandler(ErrorStatus._MEMBER_LOGIN_ID_ALREADY_EXISTS); } - if (!signUpDTO.getPassword().equals(signUpDTO.getPwCheck())) { + + String password = getDecryptedPassword(rsaId, signUpDTO.getPassword()); + String pwCheck = getDecryptedPassword(rsaId, signUpDTO.getPwCheck()); + if (!password.equals(pwCheck)) { throw new MemberHandler(ErrorStatus._MEMBER_PW_AND_PW_CHECK_DO_NOT_MATCH); } @@ -389,7 +431,7 @@ public MemberResponseDTO.MemberSignInDTO signUp(MemberRequestDTO.SignUpDTO signU .carrier(Carrier.NONE) .phone("") .loginId(signUpDTO.getLoginId()) - .password(signUpDTO.getPassword()) + .password(password) .profileImage(DEFAULT_PROFILE_IMAGE_URL) .personalInfo(false) .idInfo(false) diff --git a/src/main/java/com/example/spot/web/controller/AuthController.java b/src/main/java/com/example/spot/web/controller/AuthController.java index 32ebf603..ef894d96 100644 --- a/src/main/java/com/example/spot/web/controller/AuthController.java +++ b/src/main/java/com/example/spot/web/controller/AuthController.java @@ -2,6 +2,7 @@ import com.example.spot.api.ApiResponse; import com.example.spot.api.code.status.SuccessStatus; +import com.example.spot.web.dto.rsa.Rsa; import com.example.spot.service.auth.AuthService; import com.example.spot.validation.annotation.TextLength; import com.example.spot.web.dto.member.MemberRequestDTO; @@ -15,6 +16,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -177,14 +179,16 @@ public ApiResponse checkEmailAvailability( ## [회원 가입] 일반 회원 가입 API입니다. * 아이디(이메일)과 비밀번호 등을 포함하여 회원 가입을 진행합니다. * 주민번호 앞자리(frontRID)와 뒷자리(backRID)는 모두 String 타입입니다. + * <비밀번호>와 <비밀번호 확인>은 반드시 RSA Public Key로 암호화하여 전송해야 합니다. * 회원 가입에 성공하면, 액세스 토큰과 리프레시 토큰이 발급됩니다. * 액세스 토큰은 사용자의 정보를 인증하는데 사용되며, 리프레시 토큰은 액세스 토큰이 만료된 경우, 액세스 토큰을 재발급 하는데 사용됩니다. * 액세스 토큰이 만료된 경우, 유효한 상태의 리프레시 토큰을 통해 액세스 토큰을 재발급 받을 수 있습니다. """) @PostMapping("/sign-up") public ApiResponse signUp( - @RequestBody @Valid MemberRequestDTO.SignUpDTO signUpDTO) { - MemberResponseDTO.MemberSignInDTO memberSignUpDTO = authService.signUp(signUpDTO); + @RequestParam Long rsaId, + @RequestBody @Valid MemberRequestDTO.SignUpDTO signUpDTO) throws Exception { + MemberResponseDTO.MemberSignInDTO memberSignUpDTO = authService.signUp(rsaId, signUpDTO); return ApiResponse.onSuccess(SuccessStatus._MEMBER_CREATED, memberSignUpDTO); } @@ -217,19 +221,34 @@ public ApiResponse findPw( return ApiResponse.onSuccess(SuccessStatus._MEMBER_FOUND, findPwDTO); } + @Tag(name = "회원 관리 API - 개발 완료", description = "회원 관리 API") + @Operation(summary = "[로그인] RSA Public Key 발급 API", + description = """ + ## [로그인] 비밀번호 전송을 위해 RSA Public Key를 발급하는 API입니다. + * 서버에서 발급한 RSA Public Key와 해당 키의 식별자인 rsaId를 클라이언트에 전달합니다. + * 로그인 및 회원가입 시 해당 키를 통해 비밀번호를 암호화하여 전송해야 합니다. + """) + @PostMapping("/login/rsa") + public ApiResponse getRSAPublicKey() throws Exception { + Rsa.RSAPublicKey rsaPublicKey = authService.getRSAPublicKey(); + return ApiResponse.onSuccess(SuccessStatus._RSA_PUBLIC_KEY_FOUND, rsaPublicKey); + } @Tag(name = "회원 관리 API - 개발 완료", description = "회원 관리 API") @Operation(summary = "[로그인] 일반 로그인 API", description = """ ## [로그인] 아이디(이메일)과 비밀번호를 통해 로그인 하는 API입니다. - 로그인에 성공하면, 액세스 토큰과 리프레시 토큰이 발급됩니다. - 액세스 토큰은 사용자의 정보를 인증하는데 사용되며, 리프레시 토큰은 액세스 토큰이 만료된 경우, 액세스 토큰을 재발급 하는데 사용됩니다. - 액세스 토큰이 만료된 경우, 유효한 상태의 리프레시 토큰을 통해 액세스 토큰을 재발급 받을 수 있습니다. + * 로그인에 성공하면, 액세스 토큰과 리프레시 토큰이 발급됩니다. + * 액세스 토큰은 사용자의 정보를 인증하는데 사용되며, 리프레시 토큰은 액세스 토큰이 만료된 경우, 액세스 토큰을 재발급 하는데 사용됩니다. + * 액세스 토큰이 만료된 경우, 유효한 상태의 리프레시 토큰을 통해 액세스 토큰을 재발급 받을 수 있습니다. + * rsaId에는 RSA Public Key 발급 API를 통해 획득한 식별자(id)를 입력해야 합니다. + * 비밀번호는 반드시 RSA Public Key로 암호화하여 전송해야 합니다. """) @PostMapping("/login") public ApiResponse login( - @RequestBody @Valid MemberRequestDTO.SignInDTO signInDTO) { - MemberResponseDTO.MemberSignInDTO memberSignInDTO = authService.signIn(signInDTO); + @RequestParam Long rsaId, + @RequestBody @Valid MemberRequestDTO.SignInDTO signInDTO) throws Exception { + MemberResponseDTO.MemberSignInDTO memberSignInDTO = authService.signIn(rsaId, signInDTO); return ApiResponse.onSuccess(SuccessStatus._MEMBER_SIGNED_IN, memberSignInDTO); } diff --git a/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java b/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java index 6a8dd967..4a8580ca 100644 --- a/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java +++ b/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java @@ -19,12 +19,11 @@ public static class SignInDTO { @TextLength(max = 100) private final String loginId; - - @TextLength(max = 100) private final String password; } @Getter + @Builder @RequiredArgsConstructor public static class SignUpDTO { @@ -43,10 +42,8 @@ public static class SignUpDTO { @TextLength(min=6, max = 100) private final String loginId; - @TextLength(max = 100) private final String password; - @TextLength(max = 100) private final String pwCheck; } diff --git a/src/main/java/com/example/spot/web/dto/rsa/Rsa.java b/src/main/java/com/example/spot/web/dto/rsa/Rsa.java new file mode 100644 index 00000000..8ec91530 --- /dev/null +++ b/src/main/java/com/example/spot/web/dto/rsa/Rsa.java @@ -0,0 +1,33 @@ +package com.example.spot.web.dto.rsa; + +import lombok.*; + +import java.security.PrivateKey; +import java.security.PublicKey; +import java.time.LocalDateTime; + +@Getter +public class Rsa { + + @Getter + @Builder + @RequiredArgsConstructor + public static class RSAKey { + private final LocalDateTime createdAt; + private final PrivateKey privateKey; + private final PublicKey publicKey; + private final String modulus; + private final String exponent; + } + + @Getter + @Builder + @RequiredArgsConstructor + public static class RSAPublicKey { + private final Long rsaId; + private final String modulus; + private final String exponent; + } + + +}