diff --git a/src/main/java/com/chalnakchalnak/authservice/AuthserviceApplication.java b/src/main/java/com/chalnakchalnak/authservice/AuthserviceApplication.java index d1171f1..3b2e8ba 100644 --- a/src/main/java/com/chalnakchalnak/authservice/AuthserviceApplication.java +++ b/src/main/java/com/chalnakchalnak/authservice/AuthserviceApplication.java @@ -3,9 +3,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication @EnableFeignClients(basePackages = "com.chalnakchalnak.authservice.adapter.out.http") +@EnableJpaAuditing public class AuthserviceApplication { public static void main(String[] args) { diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/mapper/AuthVoMapper.java b/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/mapper/AuthVoMapper.java index 0732735..24ceb60 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/mapper/AuthVoMapper.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/mapper/AuthVoMapper.java @@ -49,6 +49,7 @@ public SignInRequestDto toSignInRequestDto(SignInRequestVo signInRequestVo) { public SignInResponseVo toSignInResponseVo(SignInResponseDto signInResponseDto) { return SignInResponseVo.builder() + .memberUuid(signInResponseDto.getMemberUuid()) .accessToken(signInResponseDto.getAccessToken()) .refreshToken(signInResponseDto.getRefreshToken()) .build(); diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/presentation/AuthController.java b/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/presentation/AuthController.java index a4c0fc5..a94a6ef 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/presentation/AuthController.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/presentation/AuthController.java @@ -11,6 +11,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + @RestController @RequestMapping("/api/v1/auth") @RequiredArgsConstructor @@ -119,4 +122,5 @@ public void resetPassword( authVoMapper.toResetPasswordRequestDto(resetPasswordRequestVo) ); } + } diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/vo/out/SignInResponseVo.java b/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/vo/out/SignInResponseVo.java index dc84360..b441438 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/vo/out/SignInResponseVo.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/in/web/vo/out/SignInResponseVo.java @@ -6,11 +6,13 @@ @Getter public class SignInResponseVo { + private String memberUuid; private String accessToken; private String refreshToken; @Builder - public SignInResponseVo(String accessToken, String refreshToken) { + public SignInResponseVo(String memberUuid, String accessToken, String refreshToken) { + this.memberUuid = memberUuid; this.accessToken = accessToken; this.refreshToken = refreshToken; } diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFallbackFactory.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFallbackFactory.java new file mode 100644 index 0000000..b01e866 --- /dev/null +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFallbackFactory.java @@ -0,0 +1,29 @@ +package com.chalnakchalnak.authservice.adapter.out.http.feign.member; + +import com.chalnakchalnak.authservice.application.port.dto.feign.member.CreateMemberRequestDto; +import com.chalnakchalnak.authservice.common.exception.BaseException; +import com.chalnakchalnak.authservice.common.response.BaseResponseStatus; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class MemberServiceFallbackFactory implements FallbackFactory { + + @Override + public MemberServiceFeignClient create(Throwable cause) { + return new MemberServiceFeignClient() { + @Override + public void createMember(CreateMemberRequestDto dto) { + // 예외 핸들링 로직 + throw new BaseException(BaseResponseStatus.MEMBER_SERVICE_CREATE_ERROR); + } + + @Override + public Boolean existsByNickname(String nickname) { + throw new BaseException(BaseResponseStatus.MEMBER_SERVICE_EXISTS_NICKNAME_ERROR); + } + }; + } +} diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFeignAdapter.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFeignAdapter.java deleted file mode 100644 index dc81db0..0000000 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFeignAdapter.java +++ /dev/null @@ -1,24 +0,0 @@ -//package com.chalnakchalnak.authservice.adapter.out.http.feign.member; -// -//import com.chalnakchalnak.authservice.adapter.out.http.feign.member.client.MemberServiceFeignClient; -//import com.chalnakchalnak.authservice.application.port.dto.feign.member.CreateMemberRequestDto; -//import com.chalnakchalnak.authservice.application.port.out.feign.member.MemberServicePort; -//import lombok.RequiredArgsConstructor; -//import org.springframework.stereotype.Component; -// -//@Component -//@RequiredArgsConstructor -//public class MemberServiceFeignAdapter implements MemberServicePort { -// -// private final MemberServiceFeignClient memberServiceFeignClient; -// -// @Override -// public void createMember(CreateMemberRequestDto dto) { -// memberServiceFeignClient.createMember(dto); -// } -// -// @Override -// public Boolean existsByNickname(String nickname) { -// return memberServiceFeignClient.existsByNickname(nickname); -// } -//} \ No newline at end of file diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFeignClient.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFeignClient.java index a1a3661..e8fbea6 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFeignClient.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/out/http/feign/member/MemberServiceFeignClient.java @@ -8,8 +8,12 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -//@FeignClient(name = "member-service", url = "http://member-service.default.svc.cluster.local:8080") -@FeignClient(name = "member-service", path = "api/v1/member", url = "http://localhost:8081") +@FeignClient( + name = "member-service", + path = "api/v1/member", + url = "${feign.client.member-service.url}", + fallbackFactory = MemberServiceFallbackFactory.class +) public interface MemberServiceFeignClient extends MemberServicePort { @PostMapping("/sign-up") @@ -17,4 +21,4 @@ public interface MemberServiceFeignClient extends MemberServicePort { @GetMapping("/exists/nickname/{nickname}") Boolean existsByNickname(@PathVariable String nickname); -} \ No newline at end of file +} diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/entity/AuthEntity.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/entity/AuthEntity.java index 5d05368..ee01e5c 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/entity/AuthEntity.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/entity/AuthEntity.java @@ -9,7 +9,13 @@ import lombok.NoArgsConstructor; @Entity -@Table(name = "auth") +@Table( + name = "auth", + indexes = { + @Index(name = "idx_member_id", columnList = "member_id"), + @Index(name = "idx_phone_number", columnList = "phone_number") + } +) @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class AuthEntity extends BaseEntity { diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthJpaRepository.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthJpaRepository.java index 3a9f40e..78898d0 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthJpaRepository.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthJpaRepository.java @@ -9,7 +9,7 @@ public interface AuthJpaRepository extends JpaRepository { Boolean existsByMemberId(String memberId); Boolean existsByPhoneNumber(String phoneNumber); - AuthEntity findByMemberId(String memberId); - AuthEntity findMemberIdByPhoneNumber(String phoneNumber); + Optional findByMemberId(String memberId); + Optional findMemberIdByPhoneNumber(String phoneNumber); Optional findByPhoneNumber(String phoneNumber); } diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthRepository.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthRepository.java index 540bf88..88fc147 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthRepository.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/out/persistence/mysql/repository/AuthRepository.java @@ -46,15 +46,15 @@ public Boolean existsByPhoneNumber(String phoneNumber) { @Override public Optional findByMemberId(String memberId) { - return Optional.ofNullable(authEntityMapper.toAuthResponseDto(authJpaRepository.findByMemberId(memberId))); + return authJpaRepository.findByMemberId(memberId) + .map(authEntityMapper::toAuthResponseDto); } @Override - public GetMemberIdResponseDto findMemberIdByPhoneNumber(GetMemberIdDto getMemberIdDto) { + public Optional findMemberIdByPhoneNumber(GetMemberIdDto getMemberIdDto) { - return authEntityMapper.toGetMemberIdResponseDto( - authJpaRepository.findMemberIdByPhoneNumber(getMemberIdDto.getPhoneNumber()) - ); + return authJpaRepository.findMemberIdByPhoneNumber(getMemberIdDto.getPhoneNumber()) + .map(authEntityMapper::toGetMemberIdResponseDto); } @Override diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/AuthSecurityAdapter.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/AuthSecurityAdapter.java index 08606f2..0a96b22 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/AuthSecurityAdapter.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/AuthSecurityAdapter.java @@ -51,6 +51,7 @@ public String getMemberUuidByToken(String token) { public SignInResponseDto generateAllToken(String memberUuid) { return authMapper.toSignInResponseDto( + memberUuid, jwtTokenProvider.generateAccessToken("member", memberUuid), jwtTokenProvider.generateRefreshToken("member", memberUuid) ); diff --git a/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/provider/JwtTokenProvider.java b/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/provider/JwtTokenProvider.java index 4e9ad34..13a42cd 100644 --- a/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/provider/JwtTokenProvider.java +++ b/src/main/java/com/chalnakchalnak/authservice/adapter/out/security/provider/JwtTokenProvider.java @@ -68,7 +68,7 @@ public String generateAccessToken(String role, String memberUuid) { .signWith(getSignKey()) .claim("token_type", "access") .claim("role", role) - .claim("uuid", memberUuid) + .claim("memberUuid", memberUuid) .issuedAt(now) .expiration(expiration) .compact(); @@ -88,7 +88,7 @@ public String generateRefreshToken(String role, String memberUuid) { .signWith(getSignKey()) .claim("token_type", "refresh") .claim("role", role) - .claim("uuid", memberUuid) + .claim("memberUuid", memberUuid) .issuedAt(now) .expiration(expiration) .compact(); @@ -124,8 +124,8 @@ public String extractRole(String token) { */ public Key getSignKey() { String secret = Objects.requireNonNull(env.getProperty("JWT.secret-key")); - byte[] decodedKey = Base64.getDecoder().decode(secret); +// byte[] decodedKey = Base64.getDecoder().decode(secret); - return Keys.hmacShaKeyFor(decodedKey); + return Keys.hmacShaKeyFor(secret.getBytes()); } } diff --git a/src/main/java/com/chalnakchalnak/authservice/application/mapper/AuthMapper.java b/src/main/java/com/chalnakchalnak/authservice/application/mapper/AuthMapper.java index 462feca..655c692 100644 --- a/src/main/java/com/chalnakchalnak/authservice/application/mapper/AuthMapper.java +++ b/src/main/java/com/chalnakchalnak/authservice/application/mapper/AuthMapper.java @@ -51,8 +51,9 @@ public SignInDto toSignInDto(AuthDomain authDomain) { .build(); } - public SignInResponseDto toSignInResponseDto(String accessToken, String refreshToken) { + public SignInResponseDto toSignInResponseDto(String memberUuid, String accessToken, String refreshToken) { return SignInResponseDto.builder() + .memberUuid(memberUuid) .accessToken(accessToken) .refreshToken(refreshToken) .build(); diff --git a/src/main/java/com/chalnakchalnak/authservice/application/port/dto/out/SignInResponseDto.java b/src/main/java/com/chalnakchalnak/authservice/application/port/dto/out/SignInResponseDto.java index 06eec98..2f1c068 100644 --- a/src/main/java/com/chalnakchalnak/authservice/application/port/dto/out/SignInResponseDto.java +++ b/src/main/java/com/chalnakchalnak/authservice/application/port/dto/out/SignInResponseDto.java @@ -5,11 +5,14 @@ @Getter public class SignInResponseDto { + + private String memberUuid; private String accessToken; private String refreshToken; @Builder - public SignInResponseDto(String accessToken, String refreshToken) { + public SignInResponseDto(String memberUuid, String accessToken, String refreshToken) { + this.memberUuid = memberUuid; this.accessToken = accessToken; this.refreshToken = refreshToken; } diff --git a/src/main/java/com/chalnakchalnak/authservice/application/port/out/AuthRepositoryPort.java b/src/main/java/com/chalnakchalnak/authservice/application/port/out/AuthRepositoryPort.java index 9977345..8aaa76c 100644 --- a/src/main/java/com/chalnakchalnak/authservice/application/port/out/AuthRepositoryPort.java +++ b/src/main/java/com/chalnakchalnak/authservice/application/port/out/AuthRepositoryPort.java @@ -14,7 +14,7 @@ public interface AuthRepositoryPort { // Boolean existsByNickname(String nickname); Boolean existsByPhoneNumber(String phoneNumber); Optional findByMemberId(String memberId); - GetMemberIdResponseDto findMemberIdByPhoneNumber (GetMemberIdDto getMemberIdDto); + Optional findMemberIdByPhoneNumber (GetMemberIdDto getMemberIdDto); void resetPassword(String phoneNumber, String encryptedPassword); } diff --git a/src/main/java/com/chalnakchalnak/authservice/application/service/AuthService.java b/src/main/java/com/chalnakchalnak/authservice/application/service/AuthService.java index 4a32c6b..de8282f 100644 --- a/src/main/java/com/chalnakchalnak/authservice/application/service/AuthService.java +++ b/src/main/java/com/chalnakchalnak/authservice/application/service/AuthService.java @@ -134,7 +134,9 @@ public GetMemberIdResponseDto getMemberId(GetMemberIdRequestDto getMemberIdReque throw new BaseException(BaseResponseStatus.FIND_MEMBER_ID_NOT_VERIFIED); } - return authRepositoryPort.findMemberIdByPhoneNumber(authMapper.toGetMemberIdDto(getMemberIdRequestDto)); + return authRepositoryPort.findMemberIdByPhoneNumber( + authMapper.toGetMemberIdDto(getMemberIdRequestDto) + ).orElseThrow(() -> new BaseException(BaseResponseStatus.USER_NOT_FOUND)); } @Override diff --git a/src/main/java/com/chalnakchalnak/authservice/common/config/SwaggerConfig.java b/src/main/java/com/chalnakchalnak/authservice/common/config/SwaggerConfig.java index d2a1ad5..6d3637b 100644 --- a/src/main/java/com/chalnakchalnak/authservice/common/config/SwaggerConfig.java +++ b/src/main/java/com/chalnakchalnak/authservice/common/config/SwaggerConfig.java @@ -1,32 +1,43 @@ package com.chalnakchalnak.authservice.common.config; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import org.springdoc.core.models.GroupedOpenApi; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; - -@OpenAPIDefinition( - info = @io.swagger.v3.oas.annotations.info.Info( - title = "Auth-Service API", - version = "v1", - description = "Auth 서비스" - ), security = { - @io.swagger.v3.oas.annotations.security.SecurityRequirement(name = "Authorization") -} -) - -// @Profile("!prod") @Configuration public class SwaggerConfig { + private static final String BEARER_TOKEN_PREFIX = "Bearer"; + @Bean - public GroupedOpenApi publicApi() { - String[] paths = {"/api/v1/**"}; - return GroupedOpenApi.builder() - .group("public-api") - .pathsToMatch(paths) - .build(); + public OpenAPI openAPI() { + + String securityJwtName = "JWT"; + SecurityRequirement securityRequirement = new SecurityRequirement().addList(securityJwtName); + Components components = new Components() + .addSecuritySchemes(securityJwtName, new SecurityScheme() + .name(securityJwtName) + .type(SecurityScheme.Type.HTTP) + .scheme(BEARER_TOKEN_PREFIX) + .bearerFormat(securityJwtName)); + + return new OpenAPI() + .addSecurityItem(securityRequirement) + .components(components) + .addServersItem(new Server().url("/auth-service")) + .info(apiInfo()); + } + + private Info apiInfo() { + return new Info() + .title("MSA - AUTH SERVICE 문서") + .description("00 API 테스트를 위한 Swagger UI") + .version("1.0.0"); } + } diff --git a/src/main/java/com/chalnakchalnak/authservice/common/response/BaseResponseStatus.java b/src/main/java/com/chalnakchalnak/authservice/common/response/BaseResponseStatus.java index ac1ba0d..a8e86dc 100644 --- a/src/main/java/com/chalnakchalnak/authservice/common/response/BaseResponseStatus.java +++ b/src/main/java/com/chalnakchalnak/authservice/common/response/BaseResponseStatus.java @@ -41,6 +41,11 @@ public enum BaseResponseStatus { FIND_MEMBER_ID_NOT_VERIFIED(HttpStatus.UNAUTHORIZED, 4207, "아이디 찾기를 위한 본인 인증을 먼저 진행해주세요."), RESET_PASSWORD_NOT_VERIFIED(HttpStatus.UNAUTHORIZED, 4208, "비밀번호 재설정을 위한 본인 인증을 먼저 진행해주세요."), + /** + * 4300~4399: feign client error(member-service) + */ + MEMBER_SERVICE_CREATE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 4300, "member-service 회원 생성 요청에 실패하였습니다."), + MEMBER_SERVICE_EXISTS_NICKNAME_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 4301, "member-service 닉네임 중복 확인 요청에 실패하였습니다."), /** * 4900~4999 : 기타 에러 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 82b5c2f..2c00a15 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,8 +7,8 @@ spring: datasource: url: ${MYSQL_URL} - username: ${MYSQL_USERNAME:root} - password: ${MYSQL_PASSWORD:cabbage123456!} + username: ${MYSQL_USERNAME} + password: ${MYSQL_PASSWORD} driver-class-name: com.mysql.cj.jdbc.Driver jpa: @@ -32,10 +32,15 @@ coolsms: domain: https://api.coolsms.co.kr JWT: - secret-key: ${JWT_SECRET} + secret-key: ${JWT_SECRET} token: - access-expire-time: 604800 - refresh-expire-time: 1209600 + access-expire-time: ${ACCESS_TOKEN_EXPIRE_TIME} + refresh-expire-time: ${REFRESH_TOKEN_EXPIRE_TIME} + +feign: + client: + member-service: + url: ${MEMBER_SERVICE_URL} management: endpoints: @@ -52,4 +57,5 @@ springdoc: swagger-ui: enabled: true path: /swagger-ui - config-url: /v3/api-docs/swagger-config + config-url: /auth-service/v3/api-docs/swagger-config + url: /auth-service/v3/api-docs \ No newline at end of file