Skip to content

Commit 679e3b8

Browse files
authored
[feat/OPS-324] 크롬 확장 프로그램 소셜 로그인 분기 & 소셜 로그인 테스트 API 추가. (#70)
* feat/OPS-324 : 확장 프로그램 분기 및 소셜 로그인 테스트 API 추가. * feat/OPS-324 : 테스트 로직 일부 수정. * feat/OPS-324 : 테스트 로직 일부 수정. #2 * feat/OPS-324 : 테스트 완료, 테스트 코드 제거. * feat/OPS-324 : 로그인 분기 수정. * feat/OPS-324 : state 정보를 저장하는 resolver 추가. * feat/OPS-324 : session 등록을 위한 OAuth2LoginSourceFilter 클래스 추가. * feat/OPS-324 : 해결
1 parent 9264042 commit 679e3b8

File tree

5 files changed

+86
-8
lines changed

5 files changed

+86
-8
lines changed

src/main/java/org/tuna/zoopzoop/backend/domain/auth/controller/ApiV1AuthController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import org.springframework.http.ResponseCookie;
1010
import org.springframework.http.ResponseEntity;
1111
import org.springframework.web.bind.annotation.*;
12+
import org.springframework.web.reactive.function.client.WebClient;
13+
import org.tuna.zoopzoop.backend.domain.auth.service.KakaoUserInfoService;
1214
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
1315
import org.tuna.zoopzoop.backend.domain.member.service.MemberService;
1416
import org.tuna.zoopzoop.backend.global.config.jwt.JwtProperties;
@@ -23,6 +25,8 @@ public class ApiV1AuthController {
2325
private final JwtUtil jwtUtil;
2426
private final MemberService memberService;
2527
private final JwtProperties jwtProperties;
28+
private final KakaoUserInfoService kakaoUserInfoService;
29+
private final WebClient webClient;
2630

2731
/**
2832
* 사용자 로그아웃 API
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.tuna.zoopzoop.backend.domain.auth.global;
2+
3+
import jakarta.servlet.http.HttpServletRequest;
4+
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
5+
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
6+
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
7+
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
8+
9+
public class CustomOAuth2AuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
10+
11+
private final OAuth2AuthorizationRequestResolver defaultResolver;
12+
13+
public CustomOAuth2AuthorizationRequestResolver(ClientRegistrationRepository repo, String authorizationRequestBaseUri) {
14+
this.defaultResolver = new DefaultOAuth2AuthorizationRequestResolver(repo, authorizationRequestBaseUri);
15+
}
16+
17+
@Override
18+
public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
19+
return customize(defaultResolver.resolve(request), request);
20+
}
21+
22+
@Override
23+
public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) {
24+
return customize(defaultResolver.resolve(request, clientRegistrationId), request);
25+
}
26+
27+
private OAuth2AuthorizationRequest customize(OAuth2AuthorizationRequest req, HttpServletRequest request) {
28+
if (req == null) return null;
29+
30+
String source = request.getParameter("source"); // 로그인 시작 시 전달된 source
31+
32+
OAuth2AuthorizationRequest.Builder builder = OAuth2AuthorizationRequest.from(req);
33+
34+
if ("extension".equals(source)) {
35+
// state에 source 정보를 안전하게 포함
36+
builder.state("source:extension;" + req.getState());
37+
}
38+
return builder.build();
39+
}
40+
}

src/main/java/org/tuna/zoopzoop/backend/domain/auth/handler/OAuth2FailureHandler.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ public void onAuthenticationFailure(HttpServletRequest request,
2626
// 프론트로 리다이렉트
2727
// 필요하면 쿼리 파라미터로 에러 정보 전달
2828

29+
String source = request.getParameter("source");
30+
31+
if("extension".equals(source)){
32+
String redirectUrl = redirect_domain + "/extension/callback "
33+
+ "?success=false"
34+
+ "&error=" + URLEncoder.encode(exception.getMessage(), "UTF-8");
35+
response.sendRedirect(redirectUrl);
36+
return;
37+
}
38+
2939
String redirectUrl =
3040
redirect_domain + "/auth/callback"
3141
+ "?success=false"

src/main/java/org/tuna/zoopzoop/backend/domain/auth/handler/OAuth2SuccessHandler.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import jakarta.servlet.http.HttpServletRequest;
44
import jakarta.servlet.http.HttpServletResponse;
55
import lombok.RequiredArgsConstructor;
6+
import lombok.extern.slf4j.Slf4j;
67
import org.springframework.beans.factory.annotation.Value;
78
import org.springframework.http.HttpHeaders;
89
import org.springframework.http.ResponseCookie;
@@ -22,8 +23,8 @@
2223

2324
@Component
2425
@RequiredArgsConstructor
26+
@Slf4j
2527
public class OAuth2SuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
26-
2728
private final JwtUtil jwtUtil;
2829
private final JwtProperties jwtProperties;
2930
private final MemberRepository memberRepository;
@@ -61,13 +62,30 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
6162
String accessToken = jwtUtil.generateToken(member);
6263
String refreshToken = jwtUtil.generateRefreshToken(member);
6364

64-
if ("server".equals(activeProfile)) {
65+
String source = request.getParameter("source");
66+
String state = request.getParameter("state");
67+
log.info("[OAuth2SuccessHandler] Source: {}", source);
68+
log.info("[OAuth2SuccessHandler] State: {}", state);
69+
boolean isExtension = state != null && state.contains("source:extension");
70+
71+
// 확장 프로그램에서 로그인 했을 경우.
72+
if(isExtension){
73+
String redirectUrl = redirect_domain + "/extension/callback "
74+
+ "?success=true"
75+
+ "&accessToken=" + URLEncoder.encode(accessToken, "UTF-8")
76+
+ "&refreshToken=" + URLEncoder.encode(refreshToken, "UTF-8");
77+
response.sendRedirect(redirectUrl);
78+
return;
79+
}
80+
81+
if ("http://localhost:3000".equals(redirect_domain)) {
6582
// server 환경일 때: URL 파라미터로 토큰 전달
6683
String redirectUrl = redirect_domain + "/auth/callback"
6784
+ "?success=true"
6885
+ "&accessToken=" + URLEncoder.encode(accessToken, "UTF-8")
6986
+ "&refreshToken=" + URLEncoder.encode(refreshToken, "UTF-8");
7087
response.sendRedirect(redirectUrl);
88+
7189
} else {
7290
ResponseCookie accessCookie = ResponseCookie.from("accessToken", accessToken)
7391
.httpOnly(true)
@@ -95,11 +113,6 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
95113
response.addHeader(HttpHeaders.SET_COOKIE, accessCookie.toString());
96114
response.addHeader(HttpHeaders.SET_COOKIE, refreshCookie.toString());
97115

98-
String redirectUrl = redirect_domain + "/auth/callback"
99-
+ "?success=true"
100-
+ "&accessToken=" + URLEncoder.encode(accessToken, "UTF-8")
101-
+ "&refreshToken=" + URLEncoder.encode(refreshToken, "UTF-8");
102-
103116
// 로그인 성공 후 리다이렉트.
104117
// 배포 시에 프론트엔드와 조율이 필요한 부분일 듯 함.
105118
response.sendRedirect(redirect_domain + "/auth/callback");

src/main/java/org/tuna/zoopzoop/backend/global/security/SecurityConfig.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import org.springframework.context.annotation.Bean;
55
import org.springframework.context.annotation.Configuration;
66
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7+
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
78
import org.springframework.security.web.SecurityFilterChain;
89
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
10+
import org.tuna.zoopzoop.backend.domain.auth.global.CustomOAuth2AuthorizationRequestResolver;
911
import org.tuna.zoopzoop.backend.domain.auth.handler.OAuth2SuccessHandler;
1012
import org.tuna.zoopzoop.backend.domain.auth.service.CustomOAuth2UserService;
1113
import org.tuna.zoopzoop.backend.global.security.jwt.CustomAuthenticationEntryPoint;
@@ -18,6 +20,7 @@ public class SecurityConfig {
1820
private final JwtAuthenticationFilter jwtAuthenticationFilter;
1921
private final CustomOAuth2UserService customOAuth2UserService;
2022
private final OAuth2SuccessHandler oAuth2SuccessHandler;
23+
private final ClientRegistrationRepository clientRegistrationRepository;
2124

2225
@Bean
2326
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
@@ -45,6 +48,13 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
4548
.anyRequest().authenticated()
4649
)
4750
.oauth2Login(oauth2 -> oauth2
51+
.authorizationEndpoint(authorization -> authorization
52+
.authorizationRequestResolver(
53+
new CustomOAuth2AuthorizationRequestResolver(
54+
clientRegistrationRepository,
55+
"/oauth2/authorization"
56+
)
57+
))
4858
.userInfoEndpoint(userInfo -> userInfo
4959
.userService(customOAuth2UserService)
5060
)
@@ -59,7 +69,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
5969
.exceptionHandling(ex -> ex
6070
.authenticationEntryPoint(customAuthenticationEntryPoint)
6171
)
62-
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);;
72+
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
73+
6374
return http.build();
6475
}
6576
}

0 commit comments

Comments
 (0)