| 항목 | 내용 |
|---|---|
| Language | Java 17 |
| Framework | Spring Boot 3.4.3 |
| 인증 방식 | OAuth2 (Google) + JWT |
| 세션 관리 | Stateless (세션 미사용) |
| 향후 연동 | Redis (Refresh Token 저장 예정) |
| MSA 구성 | Spring Cloud Config, Eureka, Gateway |
[클라이언트]
↓ ↑
[API Gateway] ⟷ [Eureka Server]
↓ ↑ ↑
[Auth-Service] → [Config Server]
↓ ↑
[Redis] (예정)
아키텍처 설명:
- Gateway를 통해 모든 요청이 라우팅됩니다.
- Eureka가 서비스 디스커버리 역할을 담당합니다.
- Config Server에서 중앙 집중식 설정 관리를 합니다.
- Auth-Service는 인증 서비스로, 추후 다른 마이크로서비스와 연동됩니다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/").permitAll()
.anyRequest().authenticated())
.oauth2Login(oauth -> oauth
.userInfoEndpoint(userInfo -> userInfo
.userService(customOAuth2UserService)))
.successHandler(oAuth2SuccessHandler);
return http.build();
}
CustomOAuth2UserService 등록[사용자 로그인 요청]
→ [Google 인증 페이지로 이동]
→ [OAuth2 인증 성공]
→ [CustomOAuth2UserService 실행]
→ [SuccessHandler 호출 → 직접 응답]
@Service
@RequiredArgsConstructor
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) {
// 기본 유저 정보 받아오기
OAuth2User oAuth2User = super.loadUser(userRequest);
// CustomOAuth2User로 래핑해서 리턴
return new CustomOAuth2User(oAuth2User);
}
}
@RequiredArgsConstructor
public class CustomOAuth2User implements OAuth2User {
private final OAuth2User oAuth2User;
@Override
public <A> A getAttribute(String name) {
return OAuth2User.super.getAttribute(name);
}
@Override
public Map<String, Object> getAttributes() {
return oAuth2User.getAttributes();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of();
}
@Override
public String getName() {
return oAuth2User.getName();
}
public String getEmail() {
return (String) oAuth2User.getAttributes().get("email");
}
}
구현 포인트:
- 기본 OAuth2User를 감싸서 필요한 기능을 확장.
- email 정보를 쉽게 가져올 수 있는 메소드를 추가.
- 추후 사용자 권한 관리나 추가 정보 처리를 위한 확장이 용이합니다.
OAuth2 인증이 성공하면 로그인한 사용자의 이메일 정보를 JSON으로 응답합니다.
@Component
public class OAuth2SuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
try {
CustomOAuth2User user = (CustomOAuth2User) authentication.getPrincipal();
String email = user.getEmail();
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write("{\"email\": \"" + email + "\"}");
} catch (Exception e) {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write("{\"error\": \"" + e.getMessage() + "\"}");
}
}
}
Tip:
프론트엔드 없이도 브라우저에서 바로 OAuth 로그인 성공 여부를 확인할 수 있습니다!
/oauth2/authorization/google→ 로그인 완료 → JSON 응답{ "email": "user@gmail.com" }개선 사항:
예외 처리 로직을 추가하여 에러 상황에서도 클라이언트에게 적절한 응답을 주도록 했습니다.
server:
port: 0
spring:
application:
name: auth-service
# config-server
config:
import: configserver:http://localhost:8888
security:
oauth2:
client:
registration:
google:
client-id: [YOUR_CLIENT_ID]
client-secret: [YOUR_CLIENT_SECRET]
redirect-uri: http://localhost:8080/login/oauth2/code/google
scope: profile, email
provider:
google:
authorization-uri: https://accounts.google.com/o/oauth2/v2/auth
token-uri: https://oauth2.googleapis.com/token
user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo
user-name-attribute: sub
eureka:
instance:
instance-id: ${spring.cloud.client.ip-address}:${random.value}
팁:
- Config Server에 민감한 정보(client-id, secret 등)를 보관하면 더 안전합니다.
- 랜덤 포트(
port: 0)를 사용하면 같은 서비스의 여러 인스턴스를 쉽게 실행할 수 있습니다.- Gateway 서비스에서 Auth-Service로의 라우팅 규칙도 설정해야 합니다.
| 상황 | 해결 방법 |
|---|---|
| 로그인 성공 여부 확인 불가 | SuccessHandler에서 JSON 직접 반환 |
| 사용자 정보 디버깅 필요 | Authentication 객체 로그로 찍기 |
| 프론트 없는 상태에서 테스트 | 브라우저 직접 호출로 반복 테스트 가능 |
| 예외 상황 처리 미흡 | SuccessHandler에 try-catch 추가 |
| 랜덤 포트 사용시 접근 문제 | Gateway 라우팅 + Eureka 디스커버리로 해결 |
핵심 포인트:
JWT 발급 이전 단계에서도, OAuth2 인증 성공을 독립적으로 검증할 수 있게 됨.
MSA 환경에서는 서비스 디스커버리와 게이트웨이 설정이 매우 중요함.
Postman으로 테스트:
1. OAuth2 로그인: GET /oauth2/authorization/google로 브라우저에서 요청
여기까지, OAuth2 로그인 성공 → SuccessHandler 응답 처리까지 구현 완료했습니다! 🎉
MSA 환경에서 Config Server, Eureka, Gateway와의 연동 방법도 간략히 소개했습니다.