diff --git a/build.gradle b/build.gradle index 79a77503..3b5bdc6f 100644 --- a/build.gradle +++ b/build.gradle @@ -131,8 +131,9 @@ project(":layer-external") { bootJar.enabled = false jar.enabled = true - dependencies { - implementation project(path: ':layer-common') + dependencies { + implementation project(path: ':layer-common') + implementation project(path: ':layer-domain') testImplementation platform('org.junit:junit-bom:5.9.1') testImplementation 'org.junit.jupiter:junit-jupiter' diff --git a/layer-api/src/main/java/org/layer/config/RedisConfig.java b/layer-api/src/main/java/org/layer/config/RedisConfig.java index c7d7d060..e3372349 100644 --- a/layer-api/src/main/java/org/layer/config/RedisConfig.java +++ b/layer-api/src/main/java/org/layer/config/RedisConfig.java @@ -38,7 +38,7 @@ RedisTemplate redisTemplate() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); - redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Member.class)); + redisTemplate.setValueSerializer(new StringRedisSerializer()); return redisTemplate; } diff --git a/layer-api/src/main/java/org/layer/domain/auth/controller/AuthApi.java b/layer-api/src/main/java/org/layer/domain/auth/controller/AuthApi.java new file mode 100644 index 00000000..9bad0ddc --- /dev/null +++ b/layer-api/src/main/java/org/layer/domain/auth/controller/AuthApi.java @@ -0,0 +1,152 @@ +package org.layer.domain.auth.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.layer.domain.auth.controller.dto.*; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; + +@Tag(name = "인증", description = "인증 관련 API") +public interface AuthApi { + @Operation(summary = "[인증 불필요] 로그인", description = "소셜 로그인 API(구글, 카카오), 헤더에 소셜 액세스 토큰이 필요하며, 자체 jwt 필요없음") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "로그인 성공", + headers = { + @Header(name = "Authorization", description = "소셜 액세스 토큰(Bearer 없이 토큰만)", schema = @Schema(type = "string", format = "jwt"), required = true) + }, + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name="로그인 성공", value = """ + { + "memberId": 1, + "accessToken": "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MjA2OTcyMDksImV4cCI6MTcyMDY5OTAwOSwicm9sZSI6WyJVU0VSIl0sIm1lbWJlcklkIjoxfQ.OV-RWbIPZIQlMsPMR0reFHMFq9MNBKQwf7Hw7Uo0QbJPrTEACu0MqSJlv-gMtag1PhBxo7KB5dxEDza6QI06Zw", + "refreshToken": "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MjA2OTcyMTAsImV4cCI6MTcyMTkwNjgxMCwicm9sZSI6WyJVU0VSIl0sIm1lbWJlcklkIjoxfQ.fIVauBlL3GHLrVFJ1YwWb89RFwxa84Cql2WqEu4L258ebPJ04TkAGbqrCt7i-oEKI6dbvv0KDRKXkgDQH18kTA", + "memberRole": "USER" + } + """ + ) + })), + @ApiResponse(responseCode = "400", description = "로그인 실패 - 토큰이 유효하지 않음", + headers = { + @Header(name = "Authorization", description = "소셜 액세스 토큰(Bearer 없이 토큰만)", schema = @Schema(type = "string", format = "jwt"), required = true) + }, + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name="토큰이 유효하지 않음", value = """ + { + "name": "FAIL_TO_AUTH", + "message": "인증에 실패했습니다." + } + """ + ) + })), + @ApiResponse(responseCode = "404", description = "로그인 실패 - 회원이 DB에 없음", + headers = { + @Header(name = "Authorization", description = "소셜 액세스 토큰(Bearer 없이 토큰만)", schema = @Schema(type = "string", format = "jwt"), required = true) + }, + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name="회원이 DB에 없음", value = """ + { + "name": "NOT_FOUND_USER", + "message": "유효한 유저를 찾지 못했습니다." + } + """ + ) + })) + }) + public ResponseEntity signIn(@RequestHeader("Authorization") final String socialAccessToken, @RequestBody final SignInRequest signInRequest); + + @Operation(summary = "[인증 불필요] 회원가입", description = "처음 소셜 로그인 하는 유저가 이름을 입력하는 과정, social_type은 KAKAO, GOOGLE") + @ApiResponses({ + @ApiResponse(responseCode = "201", description = "회원가입 성공", + headers = { + @Header(name = "Authorization", description = "소셜 액세스 토큰(Bearer 없이 토큰만)", schema = @Schema(type = "string", format = "jwt"), required = true) + }, + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name="회원 가입 성공. 유저의 정보를 리턴", value = """ + { + "memberId": 1, + "name": "김회고", + "email": "layerkim@kakao.com", + "memberRole": "USER", + "SocialId": "1234567890", + "socialType": "KAKAO" + } + """ + ) + })), + @ApiResponse(responseCode = "400", description = "회원가입 실패", + headers = { + @Header(name = "Authorization", description = "소셜 액세스 토큰", schema = @Schema(type = "string", format = "jwt"), required = true) + }, + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name="이미 가입된 회원", value = """ + { + "name": "NOT_A_NEW_MEMBER", + "message": "이미 가입된 회원입니다." + } + """ + ), + @ExampleObject(name="토큰이 유효하지 않음", value = """ + { + "name": "FAIL_TO_AUTH", + "message": "인증에 실패했습니다." + } + """) + })) + }) + public ResponseEntity signUp(@RequestHeader("Authorization") final String socialAccessToken, @RequestBody final SignUpRequest signUpRequest); + + @Operation(summary = "로그아웃", description = "member_id를 전달하면 DB에서 리프레시 토큰을 지웁니다.") + public ResponseEntity signOut(SignOutRequest signOutRequest); + + @Operation(summary = "[인증 불필요] 토큰 재발급", description = "member_id를 전달하면 데이터베이스에 리프레시 토큰이 남아있지 확인하고 남아있다면 jwt(access + refresh)를 새로 발급합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "201", description = "토큰 재발급 성공", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name="토큰 재발급 성공(리프레시 토큰이 DB에 남아있음, 기한 2주)", value = """ + { + "memberId": 1, + "accessToken": "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MjA2OTMyOTMsImV4cCI6MTcyMDY5NTA5Mywicm9sZSI6WyJVU0VSIl0sIm1lbWJlcklkIjoxfQ.nt4Tj1jTihS-6U7j2wkzv4VbgzTkhSPWnjBC_yXe_GiOKn3eoJ0i9NuA7Dzw6e4w_B-ab_PHzdrhfzyeVoPJOg", + "refreshToken": "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MjA2OTMyOTMsImV4cCI6MTcyMTkwMjg5Mywicm9sZSI6WyJVU0VSIl0sIm1lbWJlcklkIjoxfQ.MROa3B266VcnQqGHpvu2Lh3JiwexOM4BTYQt_3Tbc7xMY1AwS5Z51oAyVVZdO7wTLDLiUNe73DwR-7HNejWEdA" + } + """ + ) + })), + @ApiResponse(responseCode = "401", description = "토큰 재발급 실패", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name="토큰 재발급 실패(리프레시 토큰이 DB에 없음)", value = """ + { + "name": "NOT_FOUND_USER", + "message": "유효한 유저를 찾지 못했습니다." + } + """ + ) + })) + }) + public ResponseEntity reissueToken(@RequestBody ReissueTokenRequest reissueTokenRequest); + + + @Operation(summary = "회원 탈퇴", description = "header Authorization에 액세스 토큰과 memberId를 전달하여 회원 탈퇴를 할 수 있습니다.") + @ApiResponse(responseCode = "200", description = "탈퇴 성공", + headers = { + @Header(name = "Authorization", description = "자체 jwt 액세스 토큰", schema = @Schema(type = "string", format = "jwt"), required = true) + }) + public ResponseEntity withdraw(WithdrawMemberRequest withdrawMemberRequest); + + // TODO: 토큰 확인용 임시 API 추후 삭제 + @Operation(summary = "[실제 사용 X] 구글 액세스 토큰 받기", description = "서버 쪽에서 토큰을 확인하기 위한 API입니다! (실제 사용 X, 추후 삭제 예정)") + public String googleTest(@RequestParam("code") String code); + + // TODO: 토큰 확인용 임시 API 추후 삭제 + @Operation(summary = "[실제 사용 X] 카카오 액세스 토큰 받기", description = "서버 쪽에서 토큰을 확인하기 위한 API입니다! (실제 사용 X, 추후 삭제 예정)") + public Object kakaoLogin(@RequestParam(value = "code", required = false) String code); + + +} diff --git a/layer-api/src/main/java/org/layer/domain/auth/controller/AuthController.java b/layer-api/src/main/java/org/layer/domain/auth/controller/AuthController.java index 52d67e11..c0d522f5 100644 --- a/layer-api/src/main/java/org/layer/domain/auth/controller/AuthController.java +++ b/layer-api/src/main/java/org/layer/domain/auth/controller/AuthController.java @@ -18,7 +18,7 @@ @RequiredArgsConstructor @RequestMapping("/api/auth") @RestController -public class AuthController { +public class AuthController implements AuthApi { private final AuthService authService; private final GoogleService googleService; private final KakaoService kakaoService; @@ -45,23 +45,23 @@ public ResponseEntity signUp(@RequestHeader(SOCIAL_TOKEN_NAME) f // 로그아웃 @PostMapping("/sign-out") - public ResponseEntity signOut(@RequestBody Long memberId) { - authService.signOut(memberId); + public ResponseEntity signOut(@RequestBody SignOutRequest signOutRequest) { + authService.signOut(signOutRequest.memberId()); return new ResponseEntity<>(HttpStatus.OK); } // 회원 탈퇴 @PostMapping("/withdraw") - public ResponseEntity withdraw(@RequestBody Long memberId) { - authService.withdraw(memberId); - return new ResponseEntity<>(HttpStatus.OK); // TODO: 리턴 객체 수정 필요 + public ResponseEntity withdraw(WithdrawMemberRequest withdrawMemberRequest) { + authService.withdraw(withdrawMemberRequest.memberId()); + return new ResponseEntity<>(HttpStatus.OK); } // 토큰 재발급 @PostMapping("/reissue-token") - public ResponseEntity reissueToken(@RequestBody Long memberId) { + public ResponseEntity reissueToken(ReissueTokenRequest reissueTokenRequest) { return new ResponseEntity<>( - ReissueTokenResponse.of(authService.reissueToken(memberId)), + ReissueTokenResponse.of(authService.reissueToken(reissueTokenRequest.memberId())), HttpStatus.CREATED); } diff --git a/layer-api/src/main/java/org/layer/domain/auth/controller/dto/ReissueTokenRequest.java b/layer-api/src/main/java/org/layer/domain/auth/controller/dto/ReissueTokenRequest.java new file mode 100644 index 00000000..8826358e --- /dev/null +++ b/layer-api/src/main/java/org/layer/domain/auth/controller/dto/ReissueTokenRequest.java @@ -0,0 +1,6 @@ +package org.layer.domain.auth.controller.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record ReissueTokenRequest(@JsonProperty("member_id") Long memberId) { +} diff --git a/layer-api/src/main/java/org/layer/domain/auth/controller/dto/SignOutRequest.java b/layer-api/src/main/java/org/layer/domain/auth/controller/dto/SignOutRequest.java new file mode 100644 index 00000000..6c22f87c --- /dev/null +++ b/layer-api/src/main/java/org/layer/domain/auth/controller/dto/SignOutRequest.java @@ -0,0 +1,4 @@ +package org.layer.domain.auth.controller.dto; + +public record SignOutRequest(Long memberId) { +} diff --git a/layer-api/src/main/java/org/layer/domain/auth/controller/dto/WithdrawMemberRequest.java b/layer-api/src/main/java/org/layer/domain/auth/controller/dto/WithdrawMemberRequest.java new file mode 100644 index 00000000..70523928 --- /dev/null +++ b/layer-api/src/main/java/org/layer/domain/auth/controller/dto/WithdrawMemberRequest.java @@ -0,0 +1,4 @@ +package org.layer.domain.auth.controller.dto; + +public record WithdrawMemberRequest(Long memberId) { +} diff --git a/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java b/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java index 3ee52021..02c61978 100644 --- a/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java +++ b/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java @@ -29,8 +29,6 @@ public class AuthService { private final GoogleService googleService; private final JwtService jwtService; private final MemberService memberService; - private final MemberUtil memberUtil; - //== 로그인 ==// @Transactional public SignInServiceResponse signIn(final String socialAccessToken, final SocialType socialType) { @@ -67,20 +65,17 @@ public void signOut(final Long memberId) { //== 회원 탈퇴 ==// @Transactional public void withdraw(final Long memberId) { - // TODO: member 도메인에서 del_yn 바꾸기 => Member entitiy에 추가,,? - + // hard delete + memberService.withdrawMember(memberId); } - //== (리프레시 토큰을 받았을 때) 토큰 재발급 ==// + //== 토큰 재발급. redis 확인 후 재발급 ==// @Transactional public ReissueTokenServiceResponse reissueToken(final Long memberId) { - // 현재 로그인된 사용자와 memberId가 일치하는지 확인 - isValidMember(memberId); + Member member = memberService.getMemberByMemberId(memberId); + JwtToken jwtToken = jwtService.reissueToken(memberId); - // 시큐리티 컨텍스트에서 member 찾아오기 - Member member = memberUtil.getCurrentMember(); - return ReissueTokenServiceResponse.of(member, - jwtService.issueToken(member.getId(), member.getMemberRole())); + return ReissueTokenServiceResponse.of(member, jwtToken); } @@ -98,7 +93,7 @@ private MemberInfoServiceResponse getMemberInfo(SocialType socialType, String so // 현재 로그인 된 사용자와 해당 멤버 아이디가 일치하는지 확인 private void isValidMember(Long memberId) { - Member currentMember = memberUtil.getCurrentMember(); + Member currentMember = memberService.getCurrentMember(); if(!currentMember.getId().equals(memberId)) { throw new BaseCustomException(AuthExceptionType.FORBIDDEN); } diff --git a/layer-api/src/main/java/org/layer/domain/jwt/JwtAuthenticationFilter.java b/layer-api/src/main/java/org/layer/domain/jwt/JwtAuthenticationFilter.java index 7ad7c959..d9ca3cd1 100644 --- a/layer-api/src/main/java/org/layer/domain/jwt/JwtAuthenticationFilter.java +++ b/layer-api/src/main/java/org/layer/domain/jwt/JwtAuthenticationFilter.java @@ -27,7 +27,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String accessToken = getJwtFromRequest(request); - if(isValidToken(accessToken)) { + if(jwtValidator.isValidToken(accessToken)) { Long memberId = jwtValidator.getMemberIdFromToken(accessToken); List role = jwtValidator.getRoleFromToken(accessToken); setAuthenticationToContext(memberId, MemberRole.valueOf(role.get(0))); @@ -44,7 +44,11 @@ private void setAuthenticationToContext(Long memberId, MemberRole memberRole) { // 요청 헤더에서 액세스 토큰을 가져오는 메서드 private String getJwtFromRequest(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); - return (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) ? bearerToken.replace("Bearer ", ""): null; + String accessToken = null; + if(StringUtils.hasText(bearerToken)) { + accessToken = bearerToken.replace("Bearer ", ""); + } + return accessToken; } // 정상적인 토큰인지 판단하는 메서드 diff --git a/layer-api/src/main/java/org/layer/domain/jwt/JwtValidator.java b/layer-api/src/main/java/org/layer/domain/jwt/JwtValidator.java index 1b0eaca0..6981c02c 100644 --- a/layer-api/src/main/java/org/layer/domain/jwt/JwtValidator.java +++ b/layer-api/src/main/java/org/layer/domain/jwt/JwtValidator.java @@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j; import org.layer.common.exception.BaseCustomException; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import java.util.List; @@ -46,7 +47,11 @@ public List getRoleFromToken(String token) { throw new BaseCustomException(INVALID_TOKEN); } return (List) (claims.get("role")); + } + // 정상적인 토큰인지 판단하는 메서드 + public boolean isValidToken(String token) { + return StringUtils.hasText(token) && validateToken(token) == JwtValidationType.VALID_JWT; } private Claims getClaims(String token) { diff --git a/layer-api/src/main/java/org/layer/domain/jwt/service/JwtService.java b/layer-api/src/main/java/org/layer/domain/jwt/service/JwtService.java index 0524b35b..c88d1782 100644 --- a/layer-api/src/main/java/org/layer/domain/jwt/service/JwtService.java +++ b/layer-api/src/main/java/org/layer/domain/jwt/service/JwtService.java @@ -1,25 +1,29 @@ package org.layer.domain.jwt.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.layer.common.exception.BaseCustomException; -import org.layer.domain.jwt.JwtProvider; -import org.layer.domain.jwt.JwtToken; -import org.layer.domain.jwt.MemberAuthentication; +import org.layer.domain.auth.exception.TokenExceptionType; +import org.layer.domain.jwt.*; import org.layer.domain.member.entity.MemberRole; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import java.time.Duration; +import java.util.List; import java.util.Objects; import static org.layer.domain.auth.exception.TokenExceptionType.INVALID_REFRESH_TOKEN; import static org.layer.config.AuthValueConfig.ACCESS_TOKEN_EXPIRATION_TIME; import static org.layer.config.AuthValueConfig.REFRESH_TOKEN_EXPIRATION_TIME; +@Slf4j @RequiredArgsConstructor @Service public class JwtService { private final JwtProvider jwtProvider; + private final JwtValidator jwtValidator; private final RedisTemplate redisTemplate; public JwtToken issueToken(Long memberId, MemberRole memberRole) { @@ -34,10 +38,26 @@ public JwtToken issueToken(Long memberId, MemberRole memberRole) { .build(); } + // Jwt 재발급 + public JwtToken reissueToken(Long memberId) { + // 리프레시 토큰 검사 + String refreshToken = getRefreshTokenFromRedis(memberId); + if(!jwtValidator.isValidToken(refreshToken)) { + throw new BaseCustomException(TokenExceptionType.INVALID_TOKEN); // FIXME: TokenException 등으로 변경 필요 + } + + + return issueToken(memberId, getMemberRoleFromRefreshToken(refreshToken)); + } + private void saveRefreshTokenToRedis(Long memberId, String refreshToken) { redisTemplate.opsForValue().set(memberId.toString(), refreshToken, Duration.ofDays(14)); } + private String getRefreshTokenFromRedis(Long memberId) { + return (String) redisTemplate.opsForValue().get(memberId.toString()); + } + private Long getMemberIdFromRefreshToken(String refreshToken) { Long memberId = null; try { @@ -48,8 +68,20 @@ private Long getMemberIdFromRefreshToken(String refreshToken) { return memberId; } + private MemberRole getMemberRoleFromRefreshToken(String refreshToken) { + MemberRole memberRole = null; + try { + List role = jwtValidator.getRoleFromToken(refreshToken); + memberRole = MemberRole.valueOf(role.get(0)); + } catch(Exception e) { + throw new BaseCustomException(INVALID_REFRESH_TOKEN); + } + + return memberRole; + } public void deleteRefreshToken(Long memberId) { redisTemplate.delete(memberId.toString()); } + } diff --git a/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java b/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java index f29f9005..a1ef91b4 100644 --- a/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java +++ b/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java @@ -4,6 +4,7 @@ import org.layer.common.exception.BaseCustomException; import org.layer.common.exception.MemberExceptionType; import org.layer.domain.auth.controller.dto.SignUpRequest; +import org.layer.domain.jwt.SecurityUtil; import org.layer.domain.member.entity.Member; import org.layer.domain.member.entity.SocialType; import org.layer.domain.member.repository.MemberRepository; @@ -13,11 +14,13 @@ import java.util.Optional; import static org.layer.common.exception.MemberExceptionType.NOT_A_NEW_MEMBER; +import static org.layer.common.exception.MemberExceptionType.NOT_FOUND_USER; import static org.layer.domain.member.entity.MemberRole.USER; @RequiredArgsConstructor @Service public class MemberService { + private final SecurityUtil securityUtil; private final MemberRepository memberRepository; public Member findMemberById(Long memberId) { return memberRepository.findById(memberId).orElse(null); @@ -51,4 +54,21 @@ public Member saveMember(SignUpRequest signUpRequest, MemberInfoServiceResponse return member; } + public Member getCurrentMember() { + return memberRepository + .findById(securityUtil.getCurrentMemberId()) + .orElseThrow(() -> new BaseCustomException(NOT_FOUND_USER)); + } + + public Member getMemberByMemberId(Long memberId) { + return memberRepository. + findById(memberId) + .orElseThrow(() -> new BaseCustomException(NOT_FOUND_USER)); + } + + public void withdrawMember(Long memberId) { + Member currentMember = getCurrentMember(); + memberRepository.delete(currentMember); + } + } diff --git a/layer-api/src/main/java/org/layer/domain/member/service/MemberUtil.java b/layer-api/src/main/java/org/layer/domain/member/service/MemberUtil.java index 00569d31..6bf51a98 100644 --- a/layer-api/src/main/java/org/layer/domain/member/service/MemberUtil.java +++ b/layer-api/src/main/java/org/layer/domain/member/service/MemberUtil.java @@ -11,17 +11,6 @@ @RequiredArgsConstructor @Component public class MemberUtil { - private final SecurityUtil securityUtil; - private final MemberRepository memberRepository; - public Member getCurrentMember() { - return memberRepository - .findById(securityUtil.getCurrentMemberId()) - .orElseThrow(() -> new BaseCustomException(NOT_FOUND_USER)); - } - public Member getMemberByMemberId(Long memberId) { - return memberRepository. - findById(memberId) - .orElseThrow(() -> new BaseCustomException(NOT_FOUND_USER)); - } + private final MemberRepository memberRepository; } diff --git a/layer-common/build.gradle b/layer-common/build.gradle deleted file mode 100644 index e69de29b..00000000 diff --git a/layer-common/src/main/java/org/layer/common/exception/MemberExceptionType.java b/layer-common/src/main/java/org/layer/common/exception/MemberExceptionType.java index 29b67706..492bd0f9 100644 --- a/layer-common/src/main/java/org/layer/common/exception/MemberExceptionType.java +++ b/layer-common/src/main/java/org/layer/common/exception/MemberExceptionType.java @@ -10,7 +10,7 @@ public enum MemberExceptionType implements ExceptionType { * 400 */ NOT_FOUND_USER(HttpStatus.NOT_FOUND, "유효한 유저를 찾지 못했습니다."), - UNAUTHORIZED_USER(HttpStatus.UNAUTHORIZED, "로그인되지 않은 사용자입니다"), + UNAUTHORIZED_USER(HttpStatus.UNAUTHORIZED, "로그인되지 않은 사용자입니다."), FAIL_TO_AUTH(HttpStatus.BAD_REQUEST, "인증에 실패했습니다."), NOT_A_NEW_MEMBER(HttpStatus.BAD_REQUEST, "이미 가입된 회원입니다."); diff --git a/layer-external/build.gradle b/layer-external/build.gradle deleted file mode 100644 index 17ff2c7c..00000000 --- a/layer-external/build.gradle +++ /dev/null @@ -1,3 +0,0 @@ -dependencies { - implementation project(path: ':layer-domain') -} \ No newline at end of file diff --git a/layer-external/src/main/java/org/layer/oauth/dto/service/google/GoogleGetMemberInfoServiceResponse.java b/layer-external/src/main/java/org/layer/oauth/dto/service/google/GoogleGetMemberInfoServiceResponse.java index eb09b963..27c21b2e 100644 --- a/layer-external/src/main/java/org/layer/oauth/dto/service/google/GoogleGetMemberInfoServiceResponse.java +++ b/layer-external/src/main/java/org/layer/oauth/dto/service/google/GoogleGetMemberInfoServiceResponse.java @@ -3,5 +3,5 @@ import org.layer.oauth.dto.service.kakao.KakaoAccountServiceResponse; import org.layer.oauth.dto.service.kakao.KakaoGetMemberInfoServiceResponse; -public record GoogleGetMemberInfoServiceResponse(String id, String email) { +public record GoogleGetMemberInfoServiceResponse(String id, String email, String name) { } diff --git a/layer-external/src/main/java/org/layer/oauth/service/GoogleService.java b/layer-external/src/main/java/org/layer/oauth/service/GoogleService.java index 15d3619f..158f8481 100644 --- a/layer-external/src/main/java/org/layer/oauth/service/GoogleService.java +++ b/layer-external/src/main/java/org/layer/oauth/service/GoogleService.java @@ -23,7 +23,7 @@ @Slf4j @RequiredArgsConstructor @Service -public class GoogleService { +public class GoogleService implements OAuthService { private final GoogleOAuthConfig googleOAuthConfig; //== 액세스 토큰으로 사용자 정보 가져오기 ==// @@ -50,7 +50,7 @@ public MemberInfoServiceResponse getMemberInfo(final String accessToken) { } public String getToken(String code) { - log.info("redirect uri: {}", googleOAuthConfig.getGoogleRedirectUri()); +// log.info("redirect uri: {}", googleOAuthConfig.getGoogleRedirectUri()); // 토큰 요청 데이터 String uri = UriComponentsBuilder.fromOriginHeader(GOOGLE_TOKEN_URI) .toUriString(); diff --git a/layer-external/src/main/java/org/layer/oauth/service/KakaoService.java b/layer-external/src/main/java/org/layer/oauth/service/KakaoService.java index 02ee66be..7e1a457d 100644 --- a/layer-external/src/main/java/org/layer/oauth/service/KakaoService.java +++ b/layer-external/src/main/java/org/layer/oauth/service/KakaoService.java @@ -22,7 +22,7 @@ @Slf4j @RequiredArgsConstructor @Service -public class KakaoService { +public class KakaoService implements OAuthService { private final KakaoOAuthConfig kakaoOAuthConfig; public MemberInfoServiceResponse getMemberInfo(final String accessToken) { diff --git a/layer-external/src/main/java/org/layer/oauth/service/OAuthService.java b/layer-external/src/main/java/org/layer/oauth/service/OAuthService.java new file mode 100644 index 00000000..afc1c9f5 --- /dev/null +++ b/layer-external/src/main/java/org/layer/oauth/service/OAuthService.java @@ -0,0 +1,8 @@ +package org.layer.oauth.service; + +import org.layer.oauth.dto.service.MemberInfoServiceResponse; + +public interface OAuthService { + MemberInfoServiceResponse getMemberInfo(final String accessToken); + +}