Skip to content

Commit 12b53c2

Browse files
authored
[FEATURE] 카카오 OAuth 추가 (#294)
* feat(oauth): oauth 정보 등록 추가 * refactor: 패키지 이동 * refactor(user): 유저 인증 정보 dto 네이밍 변경 * refactor(user): userAuthInfo 네이밍 변경 - RequestDto로 두는 것보다 VO의 개념으로 두는 것이 더 올바르다고 판단. * test(user): 유저 공통 속성 저장 테스트 추가 * feat(kakao): 카카오 OAuth 설정 추가 * feat(kakao): 카카오 OAuth 응답 DTO 추가 * feat(oauth): 공통 oauth 정보 클래스 정적 팩토리 메서드 추가 * feat(oauth): OAuth2User 클래스에 OAuthProvider를 필드로 추가한 CustomOAuth2User 추가 * feat(oauth): defaultOAuth2UserService 의존성 주입 추가, CustomOAuth2User 사용으로 변경 * feat(oauth): OAuth 제공자 목록에 카카오 추가, 로직 개선 * feat(oauth): CustomOAuth2User 사용으로 로직 추가, 변경 - 제공자 정보를 제공 받음으로 올바른 분기 처리. - OAuth2User 사용처에서 CustomOAuth2User 사용하도록 변경. * feat(oauth): authentication to CustomOAuth2User 로직 개선, 쿠키 값 수정 - 쿠키에는 띄어쓰기가 포함될 수 없는 문제 해결. * feat(oauth): 네이버 유저 응답 정보 전용 컨버터 삭제 * feat(oauth): 주석 수정 * feat: 불필요한 파일 삭제 * feat(oauth): 소셜 로그인 URL 획득 컨트롤러 개선 * test(oauth): 테스트 수정 - 구글에서 카카오로 변경 * test(oauth): DisplayName 추가
1 parent 36bf5dd commit 12b53c2

19 files changed

+180
-58
lines changed

src/main/java/com/somemore/domains/volunteer/controller/VolunteerSignController.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package com.somemore.domains.volunteer.controller;
22

33
import com.somemore.domains.volunteer.usecase.GenerateOAuthUrlUseCase;
4-
import com.somemore.global.common.response.ApiResponse;
5-
import com.somemore.global.exception.BadRequestException;
64
import com.somemore.global.auth.signout.usecase.SignOutUseCase;
5+
import com.somemore.global.common.response.ApiResponse;
76
import io.swagger.v3.oas.annotations.Parameter;
87
import io.swagger.v3.oas.annotations.media.Schema;
98
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -32,11 +31,7 @@ public RedirectView signIn(
3231
@Parameter(name = "oauthProvider", description = "OAuth 제공자 선택", example = "naver", required = true, schema = @Schema(allowableValues = {"naver"}))
3332
@PathVariable("oauthProvider") String oauthProvider) {
3433

35-
String redirectUrl = switch (oauthProvider.toLowerCase()) {
36-
case "naver" -> generateOAuthUrlUseCase.generateUrl(oauthProvider);
37-
38-
default -> throw new BadRequestException("지원되지 않는 OAuth 제공자: " + oauthProvider);
39-
};
34+
String redirectUrl = generateOAuthUrlUseCase.generateUrl(oauthProvider);
4035

4136
return new RedirectView(redirectUrl);
4237
}

src/main/java/com/somemore/domains/volunteer/service/GenerateOAuthUrlService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.somemore.domains.volunteer.service;
22

33
import com.somemore.domains.volunteer.usecase.GenerateOAuthUrlUseCase;
4+
import com.somemore.global.auth.oauth.domain.OAuthProvider;
45
import lombok.RequiredArgsConstructor;
56
import lombok.extern.slf4j.Slf4j;
67
import org.springframework.beans.factory.annotation.Value;
@@ -18,7 +19,7 @@ public class GenerateOAuthUrlService implements GenerateOAuthUrlUseCase {
1819
@Override
1920
public String generateUrl(String oAuthProvider) {
2021
return UriComponentsBuilder.fromHttpUrl(generateBaseUrl())
21-
.pathSegment(oAuthProvider)
22+
.pathSegment(OAuthProvider.from(oAuthProvider).getProviderName())
2223
.build()
2324
.toUriString();
2425
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.somemore.global.auth.oauth.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
6+
7+
@Configuration
8+
public class OAuth2Config {
9+
10+
@Bean
11+
public DefaultOAuth2UserService defaultOAuth2UserService() {
12+
return new DefaultOAuth2UserService();
13+
}
14+
}

src/main/java/com/somemore/global/auth/oauth/converter/NaverOAuthResponseConverter.java

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.somemore.global.auth.oauth.converter;
22

33
import com.somemore.global.auth.oauth.domain.CommonOAuthInfo;
4-
import org.springframework.security.oauth2.core.user.OAuth2User;
4+
import com.somemore.global.auth.oauth.domain.CustomOAuth2User;
55

66
public interface OAuthResponseConverter {
7-
CommonOAuthInfo convert(OAuth2User oAuth2User);
7+
CommonOAuthInfo convert(CustomOAuth2User oAuth2User);
88
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.somemore.global.auth.oauth.converter;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.somemore.global.auth.oauth.domain.CommonOAuthInfo;
5+
import com.somemore.global.auth.oauth.domain.CustomOAuth2User;
6+
import com.somemore.global.auth.oauth.domain.OAuthProvider;
7+
import com.somemore.global.auth.oauth.dto.KakaoUserProfileResponseDto;
8+
import com.somemore.global.auth.oauth.dto.NaverUserProfileResponseDto;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.stereotype.Component;
11+
12+
@Component
13+
@RequiredArgsConstructor
14+
public class OAuthResponseConverterImpl implements OAuthResponseConverter {
15+
16+
private final ObjectMapper objectMapper;
17+
18+
@Override
19+
public CommonOAuthInfo convert(CustomOAuth2User oAuth2User) {
20+
OAuthProvider provider = oAuth2User.getProvider();
21+
switch (provider) {
22+
case KAKAO:
23+
KakaoUserProfileResponseDto kakaoUserProfile = objectMapper.convertValue(
24+
oAuth2User.getAttributes(),
25+
KakaoUserProfileResponseDto.class
26+
);
27+
return CommonOAuthInfo.of(
28+
OAuthProvider.KAKAO,
29+
kakaoUserProfile.id()
30+
);
31+
case NAVER:
32+
NaverUserProfileResponseDto naverUserProfile = objectMapper.convertValue(
33+
oAuth2User.getAttributes(),
34+
NaverUserProfileResponseDto.class
35+
);
36+
return CommonOAuthInfo.of(
37+
OAuthProvider.NAVER,
38+
naverUserProfile.response().id()
39+
);
40+
default:
41+
throw new IllegalArgumentException("지원하지 않는 OAuth Provider입니다.");
42+
}
43+
}
44+
}

src/main/java/com/somemore/global/auth/oauth/domain/CommonOAuthInfo.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@
33
public record CommonOAuthInfo(
44
OAuthProvider provider,
55
String oauthId) {
6+
7+
public static CommonOAuthInfo of(OAuthProvider provider, String oauthId) {
8+
return new CommonOAuthInfo(provider, oauthId);
9+
}
610
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.somemore.global.auth.oauth.domain;
2+
3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
import org.springframework.security.core.GrantedAuthority;
6+
import org.springframework.security.oauth2.core.user.OAuth2User;
7+
8+
import java.util.Collection;
9+
import java.util.Map;
10+
11+
@RequiredArgsConstructor
12+
@Getter
13+
public class CustomOAuth2User implements OAuth2User {
14+
15+
private final OAuth2User oAuth2User;
16+
private final OAuthProvider provider;
17+
18+
@Override
19+
public Map<String, Object> getAttributes() {
20+
return oAuth2User.getAttributes();
21+
}
22+
23+
@Override
24+
public Collection<? extends GrantedAuthority> getAuthorities() {
25+
return oAuth2User.getAuthorities();
26+
}
27+
28+
@Override
29+
public String getName() {
30+
return oAuth2User.getName();
31+
}
32+
33+
public static CustomOAuth2User of(OAuth2User oAuth2User, OAuthProvider oAuthProvider) {
34+
return new CustomOAuth2User(oAuth2User, oAuthProvider);
35+
}
36+
}

src/main/java/com/somemore/global/auth/oauth/domain/OAuthProvider.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
@Getter
66
public enum OAuthProvider {
7-
NAVER("naver");
7+
NAVER("naver"),
8+
KAKAO("kakao"),
9+
;
810

911
private final String providerName;
1012

@@ -14,7 +16,7 @@ public enum OAuthProvider {
1416

1517
public static OAuthProvider from(String providerName) {
1618
for (OAuthProvider provider : values()) {
17-
if (provider.providerName.equals(providerName)) {
19+
if (provider.providerName.equalsIgnoreCase(providerName)) {
1820
return provider;
1921
}
2022
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.somemore.global.auth.oauth.dto;
2+
3+
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
4+
import com.fasterxml.jackson.databind.annotation.JsonNaming;
5+
6+
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
7+
public record KakaoUserProfileResponseDto(
8+
String id // OAuth ID
9+
) {
10+
}

0 commit comments

Comments
 (0)