Skip to content

Commit

Permalink
#27 refactor: MemberAuthService 잘못된 회원가입 유효성 검사 체크 수정 && SmsCerificat…
Browse files Browse the repository at this point in the history
…ionService에서 JwtUtil 주입 제거
  • Loading branch information
psychology50 committed Oct 7, 2023
1 parent ff83cfe commit 3fd9ddd
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.kcy.fitapet.domain.member.dto.sms.SmsReq;
import com.kcy.fitapet.domain.member.dto.sms.SmsRes;
import com.kcy.fitapet.domain.member.service.component.MemberAuthService;
import com.kcy.fitapet.global.common.resolver.access.AccessToken;
import com.kcy.fitapet.global.common.resolver.access.AccessTokenInfo;
import com.kcy.fitapet.global.common.response.ErrorResponse;
import com.kcy.fitapet.global.common.response.FailureResponse;
import com.kcy.fitapet.global.common.response.SuccessResponse;
Expand Down Expand Up @@ -60,7 +62,7 @@ public class MemberApi {
@ApiResponse(responseCode = "4xx", description = "에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
})
@PostMapping("/register")
public ResponseEntity<?> register(@RequestHeader("Authorization") String accessToken, @RequestBody @Valid SignUpReq dto) {
public ResponseEntity<?> register(@AccessTokenInfo AccessToken accessToken, @RequestBody @Valid SignUpReq dto) {
Map<String, String> tokens = memberAuthService.register(accessToken, dto);
return getResponseEntity(tokens);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
import com.kcy.fitapet.domain.member.service.module.MemberSaveService;
import com.kcy.fitapet.domain.member.service.module.MemberSearchService;
import com.kcy.fitapet.domain.member.service.module.SmsService;
import com.kcy.fitapet.global.common.resolver.access.AccessToken;
import com.kcy.fitapet.global.common.response.code.ErrorCode;
import com.kcy.fitapet.global.common.response.exception.GlobalErrorException;
import com.kcy.fitapet.global.common.util.jwt.JwtUtil;
import com.kcy.fitapet.global.common.util.jwt.entity.JwtUserInfo;
import com.kcy.fitapet.global.common.util.jwt.entity.SmsAuthInfo;
import com.kcy.fitapet.global.common.util.redis.forbidden.ForbiddenTokenService;
import com.kcy.fitapet.global.common.util.redis.refresh.RefreshToken;
import com.kcy.fitapet.global.common.util.redis.refresh.RefreshTokenService;
import com.kcy.fitapet.global.common.util.redis.sms.SmsCertificationService;
import com.nimbusds.oauth2.sdk.SuccessResponse;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -46,26 +47,19 @@ public class MemberAuthService {
private final PasswordEncoder bCryptPasswordEncoder;

@Transactional
public Map<String, String> register(String authHeader, SignUpReq dto) {
String parsedToken = jwtUtil.resolveToken(authHeader);
String authenticatedPhone = jwtUtil.getPhoneNumberFromToken(parsedToken);

if (!smsCertificationService.isCorrectCertificationNumber(authenticatedPhone, parsedToken))
throw new GlobalErrorException(ErrorCode.INVALID_AUTH_CODE);
public Map<String, String> register(AccessToken accessToken, SignUpReq dto) {
String authenticatedPhone = jwtUtil.getPhoneNumberFromToken(accessToken.accessToken());
smsCertificationService.removeCertificationNumber(authenticatedPhone);

Member requestMember = dto.toEntity(authenticatedPhone);
requestMember.encodePassword(bCryptPasswordEncoder);
validateMember(requestMember);
log.debug("회원가입 요청: {}", requestMember);

if (memberSearchService.isExistMemberByUidOrEmailOrPhone(requestMember.getUid(), requestMember.getEmail(), requestMember.getPhone()))
throw new GlobalErrorException(ErrorCode.DUPLICATE_USER_INFO_ERROR);

Member registeredMember = memberSaveService.saveMember(requestMember);
log.debug("회원가입 완료: {}", registeredMember);
JwtUserInfo jwtUserInfo = JwtUserInfo.from(registeredMember);

return generateToken(jwtUserInfo);
return generateToken(JwtUserInfo.from(registeredMember));
}

@Transactional
Expand All @@ -74,9 +68,7 @@ public Map<String, String> login(SignInReq dto) {
if (member.checkPassword(dto.password(), bCryptPasswordEncoder))
throw new GlobalErrorException(ErrorCode.NOT_MATCH_PASSWORD_ERROR);

JwtUserInfo jwtUserInfo = JwtUserInfo.from(member);

return generateToken(jwtUserInfo);
return generateToken(JwtUserInfo.from(member));
}

@Transactional
Expand Down Expand Up @@ -123,13 +115,15 @@ public SmsRes sendCertificationNumber(SmsReq dto) {

@Transactional
public String checkCertificationNumber(SmsReq smsReq, String requestCertificationNumber) {
String token = null;
if (smsCertificationService.isCorrectCertificationNumber(smsReq.to(), requestCertificationNumber)) {
log.info("인증번호 일치");
token = smsCertificationService.issueSmsAuthToken(smsReq.to());
if (!smsCertificationService.isCorrectCertificationNumber(smsReq.to(), requestCertificationNumber)) {
log.warn("인증번호 불일치");
throw new GlobalErrorException(ErrorCode.INVALID_AUTH_CODE);
}

return (token != null) ? token : "";
String token = jwtUtil.generateSmsAuthToken(SmsAuthInfo.of(1L, smsReq.to()));
smsCertificationService.saveSmsAuthToken(smsReq.to(), token);

return token;
}

private void checkSmsStatus(String requestPhone, SensRes sensRes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ private String reissueAccessToken(HttpServletRequest request, HttpServletRespons

JwtUserInfo userInfo = jwtUtil.getUserInfoFromToken(requestRefreshToken);
String reissuedAccessToken = jwtUtil.generateAccessToken(userInfo);
response.addHeader(ACCESS_TOKEN.getValue(), reissuedAccessToken);
response.addHeader(REISSUED_ACCESS_TOKEN.getValue(), reissuedAccessToken);
return reissuedAccessToken;
} catch (AuthErrorException e) {
log.error("Failed to reissue access token: {}", e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
@Getter
public enum AuthConstants {
AUTH_HEADER("Authorization"), TOKEN_TYPE("Bearer "),
ACCESS_TOKEN("accessToken"), REFRESH_TOKEN("refreshToken");
ACCESS_TOKEN("accessToken"), REFRESH_TOKEN("refreshToken"),
REISSUED_ACCESS_TOKEN("X-Access-Token");

private final String value;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kcy.fitapet.global.common.util.jwt;

import com.kcy.fitapet.global.common.util.jwt.entity.JwtUserInfo;
import com.kcy.fitapet.global.common.util.jwt.entity.SmsAuthInfo;
import com.kcy.fitapet.global.common.util.jwt.exception.AuthErrorException;

import java.util.Date;
Expand Down Expand Up @@ -30,10 +31,10 @@ public interface JwtUtil {

/**
* 사용자 정보 기반으로 SMS 인증 토큰을 생성하는 메서드
* @param phoneNumber String : 수신자 번호
* @param user SmsAuthInfo : 사용자 정보
* @return String : 토큰
*/
String generateSmsAuthToken(String phoneNumber);
String generateSmsAuthToken(SmsAuthInfo user);

/**
* token으로 부터 사용자 정보를 추출하는 메서드
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.kcy.fitapet.domain.member.domain.RoleType;
import com.kcy.fitapet.global.common.util.exception.JwtErrorCodeUtil;
import com.kcy.fitapet.global.common.util.jwt.entity.JwtDto;
import com.kcy.fitapet.global.common.util.jwt.entity.JwtUserInfo;
import com.kcy.fitapet.global.common.util.jwt.entity.SmsAuthInfo;
import com.kcy.fitapet.global.common.util.jwt.exception.AuthErrorCode;
import com.kcy.fitapet.global.common.util.jwt.exception.AuthErrorException;
import io.jsonwebtoken.*;
Expand Down Expand Up @@ -82,12 +84,12 @@ public String generateRefreshToken(JwtUserInfo user) {

@Override
@SuppressWarnings("deprecation")
public String generateSmsAuthToken(String phoneNumber) {
public String generateSmsAuthToken(SmsAuthInfo user) {
final Date now = new Date();

return Jwts.builder()
.setHeader(createHeader())
.setClaims(Map.of(PHONE_NUMBER, phoneNumber))
.setClaims(Map.of(PHONE_NUMBER, user.phoneNumber()))
.signWith(SignatureAlgorithm.HS256, createSignature())
.setExpiration(createExpireDate(now, smsAuthExpirationTime.toMillis()))
.compact();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.kcy.fitapet.global.common.util.jwt.entity;

public interface JwtDto {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import lombok.ToString;

@Builder
public record JwtUserInfo(
public record JwtUserInfo (
Long id,
RoleType role
) {
) implements JwtDto {
public static JwtUserInfo of(Long id, RoleType role) {
return new JwtUserInfo(id, role);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kcy.fitapet.global.common.util.jwt.entity;

import lombok.Builder;

@Builder
public record SmsAuthInfo(
Long userId,
String phoneNumber
) implements JwtDto {
public static SmsAuthInfo of(Long userId, String phoneNumber) {
return new SmsAuthInfo(userId, phoneNumber);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ public enum AuthErrorCode implements StatusCode {
* 403 FORBIDDEN: 인증된 클라이언트가 권한이 없는 자원에 접근
*/
FORBIDDEN_ACCESS_TOKEN(FORBIDDEN, "해당 토큰에는 엑세스 권한이 없습니다"),
MISMATCHED_REFRESH_TOKEN(FORBIDDEN, "리프레시 토큰의 유저 정보가 일치하지 않습니다");
MISMATCHED_REFRESH_TOKEN(FORBIDDEN, "리프레시 토큰의 유저 정보가 일치하지 않습니다"),

/**
* 500 INTERNAL_SERVER_ERROR: 서버 내부 에러
*/
INVALID_JWT_DTO_FORMAT(INTERNAL_SERVER_ERROR, "서버 내부 에러가 발생했습니다.");

private final HttpStatus httpStatus;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ public interface SmsCertificationService {
String issueCertificationNumber(String phoneNumber);

/**
* SMS 인증 완료 후 계정 생성을 위한 토큰 발행
* SMS 인증 완료 후 계정 생성을 위한 토큰 저장
* @param phoneNumber : String
* @return String : 토큰
* @param accessToken : String
*/
String issueSmsAuthToken(String phoneNumber);
void saveSmsAuthToken(String phoneNumber, String accessToken);

/**
* 인증번호 확인
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ public class SmsCertificationServiceImpl implements SmsCertificationService {
private final SmsCertificationRepository smsCertificationRepository;
private final RedisTemplate<String, SmsCertification> redisTemplate;

private final JwtUtil jwtUtil;

@Override
public String issueCertificationNumber(String phoneNumber) {
StringBuilder sb = new StringBuilder();
Expand All @@ -36,10 +34,8 @@ public String issueCertificationNumber(String phoneNumber) {
}

@Override
public String issueSmsAuthToken(String phoneNumber) {
String token = jwtUtil.generateSmsAuthToken(phoneNumber);
smsCertificationRepository.save(SmsCertification.of(phoneNumber, token));
return token;
public void saveSmsAuthToken(String phoneNumber, String accessToken) {
smsCertificationRepository.save(SmsCertification.of(phoneNumber, accessToken));
}

@Override
Expand Down

0 comments on commit 3fd9ddd

Please sign in to comment.