Skip to content

Commit c7b41ee

Browse files
committed
[FIX] oauth 방식 수정
1 parent 5587237 commit c7b41ee

File tree

11 files changed

+186
-166
lines changed

11 files changed

+186
-166
lines changed

src/main/java/com/example/ai_tutor/domain/auth/application/CustomDefaultOAuth2UserService.java

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import lombok.RequiredArgsConstructor;
2020
import org.springframework.transaction.annotation.Transactional;
2121

22+
import java.util.Map;
2223
import java.util.Optional;
2324

2425
@Slf4j
@@ -27,48 +28,37 @@
2728
public class CustomDefaultOAuth2UserService extends DefaultOAuth2UserService {
2829

2930
private final UserRepository userRepository;
31+
private final OAuth2UserInfoFactory oAuth2UserInfoFactory;
3032

3133
@Override
34+
@Transactional
3235
public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException {
36+
log.info("loadUser Start");
3337
OAuth2User oAuth2User = super.loadUser(oAuth2UserRequest);
34-
log.info("OAuth2 user loaded: {}", oAuth2User);
35-
try {
36-
log.info("Processing OAuth2 user: {}", oAuth2User);
37-
return processOAuth2User(oAuth2UserRequest, oAuth2User);
38-
} catch (Exception e) {
39-
log.info("Error processing OAuth2 user: {}", e.getMessage());
40-
DefaultAssert.isAuthentication(e.getMessage());
38+
String registrationId = oAuth2UserRequest.getClientRegistration().getRegistrationId();
39+
Map<String, Object> attributes = oAuth2User.getAttributes();
40+
User user = this.processOAuth2User(registrationId, attributes);
41+
log.info("Processing OAuth2 user: {}", oAuth2User);
42+
UserPrincipal userPrincipal = UserPrincipal.create(user);
43+
log.info("OAuth2 로그인 UserPrincipal 생성됨 - UUID: {}", userPrincipal.getUsername());
44+
45+
return userPrincipal;
4146
}
42-
return null;
43-
}
4447

45-
private OAuth2User processOAuth2User(OAuth2UserRequest oAuth2UserRequest, OAuth2User oAuth2User) {
46-
OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(oAuth2UserRequest.getClientRegistration().getRegistrationId(), oAuth2User.getAttributes());
48+
private User processOAuth2User(String registrationId, Map<String, Object> attributes) {
49+
OAuth2UserInfo oAuth2UserInfo = oAuth2UserInfoFactory.getOAuthUserInfo(registrationId, attributes);
4750
DefaultAssert.isAuthentication(!oAuth2UserInfo.getEmail().isEmpty());
48-
49-
Optional<User> userOptional = userRepository.findByEmail(oAuth2UserInfo.getEmail());
50-
User user;
51-
if(userOptional.isPresent()) {
52-
user = userOptional.get();
53-
DefaultAssert.isAuthentication(user.getProvider().equals(Provider.valueOf(oAuth2UserRequest.getClientRegistration().getRegistrationId())));
54-
user = updateExistingUser(user, oAuth2UserInfo);
55-
log.info("User updated: {}", user);
56-
} else {
57-
user = registerNewUser(oAuth2UserRequest, oAuth2UserInfo);
58-
log.info("New user registered: {}", user);
59-
}
60-
61-
log.info("OAuth2 user processed: {}", user);
62-
return UserPrincipal.create(user, oAuth2User.getAttributes());
51+
Optional<User> user = userRepository.findByEmail(oAuth2UserInfo.getEmail());
52+
return user.orElseGet(() -> this.registerNewUser(oAuth2UserInfo, registrationId));
6353
}
6454

65-
private User registerNewUser(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo oAuth2UserInfo) {
55+
private User registerNewUser(OAuth2UserInfo oAuth2UserInfo, String registrationId) {
6656
User user = User.builder()
6757
.name(oAuth2UserInfo.getName())
6858
.email(oAuth2UserInfo.getEmail())
6959
.password("oauth-only")
70-
.provider(Provider.valueOf(oAuth2UserRequest.getClientRegistration().getRegistrationId()))
71-
.providerId(oAuth2UserInfo.getId())
60+
.provider(registrationId)
61+
.providerId(oAuth2UserInfo.getProviderId())
7262
.build();
7363

7464
return userRepository.save(user);

src/main/java/com/example/ai_tutor/domain/user/domain/User.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import com.example.ai_tutor.domain.common.BaseEntity;
44
import com.example.ai_tutor.domain.professor.domain.Professor;
55
import jakarta.persistence.*;
6+
import lombok.AllArgsConstructor;
67
import lombok.Builder;
78
import lombok.Getter;
89
import lombok.NoArgsConstructor;
910

1011
@Entity
1112
@Table(name="User")
1213
@NoArgsConstructor
14+
@AllArgsConstructor
15+
@Builder
1316
@Getter
1417
public class User extends BaseEntity {
1518
@Id
@@ -26,8 +29,7 @@ public class User extends BaseEntity {
2629
@Column(name="password")
2730
private String password;
2831

29-
@Enumerated(EnumType.STRING)
30-
private Provider provider;
32+
private String provider;
3133

3234
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
3335
@JoinColumn(name="professor_id")
@@ -38,17 +40,6 @@ public class User extends BaseEntity {
3840
@Enumerated(EnumType.STRING)
3941
private Role role = Role.PROFESSOR;
4042

41-
42-
@Builder
43-
public User(String name, String email, String password, Provider provider, String providerId){
44-
this.name = name;
45-
this.email = email;
46-
this.password = password;
47-
this.provider = provider;
48-
this.professor = new Professor(name, this);
49-
this.providerId = providerId;
50-
}
51-
5243
public void updateProfessor(Professor professor) { this.professor = professor; }
5344

5445
public void updateName(String name) { this.name = name; }
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.example.ai_tutor.global.config.security.auth;
2+
3+
import jakarta.servlet.FilterChain;
4+
import jakarta.servlet.ServletException;
5+
import jakarta.servlet.http.HttpServletRequest;
6+
import jakarta.servlet.http.HttpServletResponse;
7+
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
8+
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
9+
import org.springframework.stereotype.Component;
10+
11+
import java.io.IOException;
12+
13+
@Component
14+
public class CustomOAuth2AuthorizationRequestRedirectFilter extends OAuth2AuthorizationRequestRedirectFilter {
15+
16+
public CustomOAuth2AuthorizationRequestRedirectFilter(OAuth2AuthorizationRequestResolver customOAuth2AuthorizationRequestResolver) {
17+
super(customOAuth2AuthorizationRequestResolver);
18+
}
19+
20+
@Override
21+
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
22+
throws IOException, ServletException {
23+
// 프론트엔드에서 전달된 redirect_url과 error_redirect_url 쿼리 파라미터를 처리
24+
String redirectUrl = request.getParameter("redirect_url");
25+
String errorRedirectUrl = request.getParameter("error_redirect_url");
26+
27+
// 쿼리 파라미터가 있다면 세션에 저장
28+
if (redirectUrl != null) {
29+
request.getSession().setAttribute("OAUTH2_REDIRECT_URL", redirectUrl);
30+
}
31+
32+
if (errorRedirectUrl != null) {
33+
request.getSession().setAttribute("OAUTH2_ERROR_REDIRECT_URL", errorRedirectUrl);
34+
}
35+
36+
// 기존 필터 체인 동작
37+
super.doFilterInternal(request, response, filterChain);
38+
}
39+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.example.ai_tutor.global.config.security.auth;
2+
3+
4+
import jakarta.servlet.http.HttpServletRequest;
5+
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
6+
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
7+
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
8+
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
9+
import org.springframework.stereotype.Component;
10+
11+
@Component
12+
public class CustomOAuth2AuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
13+
14+
private final DefaultOAuth2AuthorizationRequestResolver delegate;
15+
16+
public CustomOAuth2AuthorizationRequestResolver(ClientRegistrationRepository clientRegistrationRepository) {
17+
this.delegate = new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository, "/oauth2/authorize");
18+
19+
this.delegate.setAuthorizationRequestCustomizer(builder -> {
20+
String registrationId = (String) builder.build().getAttributes().get("registration_id");
21+
if ("google".equals(registrationId)) {
22+
builder.additionalParameters(params -> params.put("prompt", "select_account"));
23+
}
24+
});
25+
}
26+
27+
@Override
28+
public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
29+
return delegate.resolve(request);
30+
}
31+
32+
@Override
33+
public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) {
34+
return delegate.resolve(request, clientRegistrationId);
35+
}
36+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.example.ai_tutor.global.config.security.auth;
2+
3+
import java.util.Map;
4+
5+
public class GoogleOAuth2UserInfo extends OAuth2UserInfo {
6+
public GoogleOAuth2UserInfo(Map<String, Object> attributes) {
7+
super(attributes);
8+
}
9+
10+
@Override
11+
public String getEmail() {
12+
return attributes.get("email").toString();
13+
}
14+
15+
@Override
16+
public String getProviderId() {
17+
return attributes.get("sub").toString();
18+
}
19+
20+
@Override
21+
public String getName() {
22+
return "";
23+
}
24+
}
25+
Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
11
package com.example.ai_tutor.global.config.security.auth;
22

3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
36
import java.util.Map;
47

8+
9+
@Getter
10+
@AllArgsConstructor
511
public abstract class OAuth2UserInfo {
612
protected Map<String, Object> attributes;
713

8-
public OAuth2UserInfo(Map<String, Object> attributes) {
9-
this.attributes = attributes;
10-
}
11-
12-
public Map<String, Object> getAttributes() {
13-
return attributes;
14-
}
15-
16-
public abstract String getProvider();
17-
18-
public abstract String getId();
19-
2014
public abstract String getName();
21-
2215
public abstract String getEmail();
23-
24-
public abstract String getImageUrl();
16+
public abstract String getProviderId();
2517
}
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package com.example.ai_tutor.global.config.security.auth;
22

3-
import com.example.ai_tutor.domain.user.domain.Provider;
4-
import com.example.ai_tutor.global.DefaultAssert;
5-
import com.example.ai_tutor.global.config.security.auth.company.Google;
3+
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
4+
import org.springframework.stereotype.Component;
65

76
import java.util.Map;
87

8+
@Component
99
public class OAuth2UserInfoFactory {
10-
public static OAuth2UserInfo getOAuth2UserInfo(String registrationId, Map<String, Object> attributes) {
11-
if(registrationId.equalsIgnoreCase(Provider.google.toString())) {
12-
return new Google(attributes);
13-
} else {
14-
DefaultAssert.isAuthentication("해당 oauth2 기능은 지원하지 않습니다.");
15-
}
16-
return null;
10+
public OAuth2UserInfo getOAuthUserInfo(String registrationId, Map<String, Object> attributes) {
11+
return switch (registrationId) {
12+
13+
case "google" -> new GoogleOAuth2UserInfo(attributes);
14+
15+
default -> throw new OAuth2AuthenticationException("지원하지 않는 소셜 로그인입니다.");
16+
};
1717
}
1818
}

src/main/java/com/example/ai_tutor/global/config/security/auth/company/Google.java

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/main/java/com/example/ai_tutor/global/config/security/handler/CustomSimpleUrlAuthenticationFailureHandler.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,29 @@
2222
@Component
2323
@Slf4j
2424
public class CustomSimpleUrlAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
25-
private final CustomAuthorizationRequestRepository customAuthorizationRequestRepository;
2625

2726
@Override
2827
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
2928
log.error("OAuth2 로그인 실패: {}", exception.getMessage());
3029

30+
String errorMessage = exception.getMessage();
31+
3132
log.info("Request URI: {}", request.getRequestURI());
3233
log.info("Query String: {}", request.getQueryString());
3334
log.info("Cookies: {}", Arrays.toString(request.getCookies()));
3435

35-
String targetUrl = CustomCookie.getCookie(request, REDIRECT_URI_PARAM_COOKIE_NAME)
36-
.map(Cookie::getValue)
37-
.orElse(("/"));
36+
// 세션에서 error_redirect_url 가져오기
37+
String errorRedirectUrl = (String) request.getSession().getAttribute("OAUTH2_ERROR_REDIRECT_URL");
38+
if (errorRedirectUrl == null || errorRedirectUrl.isEmpty()) {
39+
errorRedirectUrl = "https://ai-tutor.ac.kr/login?error"; // 기본 오류 리디렉션 URL
40+
}
3841

39-
targetUrl = UriComponentsBuilder.fromUriString(targetUrl)
40-
.queryParam("error", "invalid_request")
41-
.build()
42-
.toUriString();
43-
customAuthorizationRequestRepository.removeAuthorizationRequestCookies(request, response);
42+
// 에러를 쿼리 파라미터에 추가
43+
errorRedirectUrl = UriComponentsBuilder.fromUriString(errorRedirectUrl)
44+
.queryParam("error", errorMessage)
45+
.build().toUriString();
4446

45-
getRedirectStrategy().sendRedirect(request, response, targetUrl);
47+
log.info("OAuth2 로그인 실패 - 에러 메시지: {}", errorMessage);
48+
getRedirectStrategy().sendRedirect(request, response, errorRedirectUrl);
4649
}
4750
}

0 commit comments

Comments
 (0)