BE/Spring Boot

[Spring Boot] OAuth2 소셜 로그인 (카카오, 구글)

셰욘 2025. 3. 1. 23:49
728x90

스프링 부트에서 소셜 로그인을 구현하기

 

OAuth 라이브러리 추가

 

build.gradle에 추가

implementation 'org.springframework.security:spring-security-oauth2-client'

 


카카오 로그인 설정


https://developers.kakao.com/docs/latest/ko/kakaologin/common 

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

✅ Redirect URI 설정

카카오 어플리케이션에서 Redirect URI 설정해준다.

http://localhost:8080/login/oauth2/code/kakao

 

✅ application.yml에 카카오 설정


application.yml

spring:
  security:
    oauth2:
      client:
        registration:
          kakao:
            client-id: ${KAKAO_CLIENT_ID}   # 내 어플리케이션 - REST API 앱 키
            redirect-uri: ${KAKAO_REDIRECT_URI}    # 내 어플리케이션 - redirect uri
            authorization-grant-type: authorization_code  # 카카오에서 지정한 값
            client-authentication-method: none
            client-name: Kakao
            scope:  # 카카오한테서 뭘 받아올 것인가
              - profile_nickname
        provider:
          kakao:
            authorization-uri: https://kauth.kakao.com/oauth/authorize
            token-uri: https://kauth.kakao.com/oauth/token
            user-info-uri: https://kapi.kakao.com/v2/user/me
            user-name-attribute: id

 

 

 

✅ 스프링 프로젝트에서 설정

Service

OAuth2UserService 를 상속 받은 UserService 클래스를 생성한다.

 

회원 정보를 가져와서 DB에 회원이 있는지 확인을 해주고, 

만약 회원 정보가 없다면 카카오에서 가져온 이메일로 회원가입 처리를 해준다.

 

@RequiredArgsConstructor
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
    // @Bean으로 등록되어 있지 않기 때문에 직접 객체 생성
    private final DefaultOAuth2UserService defaultOAuth2UserService = new DefaultOAuth2UserService();

    private final UserService userService;
    
    // 회원 정보를 가져와서 OAuth2User를 반환
    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        // 회원 정보 가져오기
        OAuth2User oAuth2User = defaultOAuth2UserService.loadUser(userRequest);

        User user = (User) userService.loadUserByUsername(oAuth2User.getName());
        // 내 웹에 회원 가입이 안 되어 있으면
        if (user == null) {
            // 회원가입 처리
            userService.signup(UserDto.SignupRequest.builder()
                    .email(user.getEmail())
                    .build());
        }

        return null;
    }
}

 

 


User

OAuth2User 를 상속 받은 User 클래스를 생성한다.

 

사용자 정보 또는 사용자 이메일을 반환하고, 권한이 "ROLE_USER"로 반환되게 설정해준다.

public class CustomOAuth2User implements OAuth2User {
    private User user;

    public CustomOAuth2User(User user) {
        this.user = user;
    }

    // 사용자 정보 반환
    @Override
    public Map<String, Object> getAttributes() {
        return Map.of("nickname", user.getEmail());
    }

    // 사용자 이메일 반환
    @Override
    public String getName() {
        return user.getEmail();
    }

    // 권한이 기본 사용자로 반환되게 설정
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");

        authorities.add(authority);
        return authorities;
    }
}

 


Security 설정

SecurityConfig 클래스의 configure 메소드에 추가

@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {

    http.oauth2Login(config -> {
        config.userInfoEndpoint(endpoint ->
                endpoint.userService(customOAuth2UserService));
    });
    
    // 생략
}

 

 

 

 

http://localhost:8080/oauth2/authorization/kakao

 

위의 주소로 접속하면 oAuth2User에 사용자 정보가 들어오는 걸 확인할 수 있다.

 

 

 

oauth handler 생성

토큰을 생성해서 쿠키에 설정해준다.

public class OAuth2SuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        OAuth2User user = (OAuth2User) authentication.getPrincipal();
        String jwtToken = JwtUtil.generateToken(0L, user.getName());

        ResponseCookie cookie = ResponseCookie
                .from("ATOKEN", jwtToken)
                .path("/")
                .httpOnly(true)
                .secure(true)
                .maxAge(Duration.ofHours(1L))
                .build();

        response.setHeader(HttpHeaders.SET_COOKIE, cookie.toString());
    }
}

 

 

 

생성 후 securityconfig에 등록해준다.

http.oauth2Login(config -> {
    config.successHandler(new OAuth2SuccessHandler());   // 생성한 handle 등록
    config.userInfoEndpoint(endpoint ->
            endpoint.userService(customOAuth2UserService));
});

 

 

 

 JWT 토큰이 생성돼서 쿠키에 설정됐다.

 

 


구글 로그인 설정

아래 주소에서 설정해준다.

 

https://cloud.google.com/apis?hl=ko

 

https://cloud.google.com/apis?hl=ko

 

cloud.google.com

 

✅ 구글 프로젝트 생성

 

프로젝트를 만들어준다.


✅ 구글 인증 플랫폼 구성

구글 인증 플랫폼을 검색해서 들어가준다.

 

 

시작하기 눌러서 구성하기

 

 

 

프로젝트 구성 정보에서

앱 이름과 사용자 지원 이메일을 입력해준다.

 

 

모든 테스트 사용자가 사용할 수 있게 대상 외부로 설정해준다.

외부로 설정 후 만들기 클릭

 

 


✅ 구글 인증 플랫폼 - 클라이언트 만들기

 

왼쪽 탭에 클라이언트 - 클라이언트 만들기로 만들어준다

 

 

애플리케이션 유형을 '웹 애플리케이션' 으로 선택해주고, 이름을 입력한다.

 

 

그러면 클라이언트가 생성된 걸 확인할 수 있다.

 

 

 

리디렉션 URI 설정

클라이언트 이름을 클릭하면 설정 창이 뜬다.

 

리디렉션 URI 를 아래 주소로 설정해준다.

http://localhost:8080/login/oauth2/code/google

 

 

 

 

 

 

 

✅ application.yml 설정

 

Google 인증 플랫폼 - 클라이언트에서 클라이언트 ID와 Secret을 넣어준다.

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: ${GOOGLE_CLIENT_ID}  // 구글 클라이언트 ID
            client-secret: ${GOOGLE_CLIENT_SECRET}
            scope:
              - email
              - profile

 

 

 

 

http://localhost:8080/oauth2/authorization/google 

위에 주소로 들어가면 구글 계정 선택 창이 뜨는 걸 확인할 수 있다.

계정 선택해서 로그인해주면 끝!

 

 

728x90