OAuth2의 이해
OAuth 2.0은 인증을 위한 업계 표준 프로토콜로 클라이언트 개발자의 단순성에 초점을 맞추면서 다양한 장치에 대한 특정 인증 흐름을 제공합니다. 이 사양은 2012년 10월 IETF OAuth 워킹 그룹 내에서 개발되었습니다.
OAuth 2 인증 흐름은 리소스 소유자에게 인가 요청을 하여 인가 Code를 받고, 인가 Code를 이용하여 인증 서버에서 액세스 토큰을 받은 후, 액세스 토큰을 이용하여 자원 서버에서 필요한 리소스를 조회하는 간단한 개념입니다.
* Spring Social의 지원 종료
Spring Security 5가 출시됨(2018년 03월 06일)에 따라 기존에 사용하던 Spring Social은
Spring Security의 일부가되었습니다. Spring Social은 2019년 7월 3일에 종료되었습니다.
* WebSecurityConfigurerAdapter의 Deprecated (2022년 2월 21일)
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
Spring Security 5.7.0-M2에서는 사용자가 구성 요소 기반 보안 구성으로 이동하도록 권장하므로 더 이상 사용되지 않습니다
카카오 디벨로퍼스의 로그인 설정은 가이드를 참고하여 먼저 설정합니다.
Spring Security 5에서 OAuth2 사용하기
SpringToolSuite4 또는 VisualStudio Code의 플러그인을 설치하여 Spring Stater Project 기능을 이용해서 프로젝트를 생성합니다. spring.io/tools
File > New > Spring Starter Project
java 소스 코드 폴더에 SecurityConfig.java 파일과 KakaoOAuth2UserService.java 파일
resources 폴더에 application.yml 파일을 생성합니다.
Spring Tools 4 for Visual Studio Code | Spring Tools 4 for Eclipse |
|
▶ application.yml
spring:
security:
oauth2:
client:
registration:
kakao:
authorization-grant-type: authorization_code
client-id: 444444444444444479e933556a21e8
client-secret: QQQQQQQQQQQQQQQQuOfOLzjZMc5q1U
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
scope:
- profile
- account_email
client-authentication-method: client_secret_post
client-name: Kakao
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
※ client-id에는 REST-API-KEY를 세팅합니다.
※ @RequiredArgsConstructor 어노테이션 사용을 위해 build.gradle파일에 annotationProcessor도 추가합니다.
annotationProcessor 'org.projectlombok:lombok'
▶ SecurityConfig.java
- WebSecurityConfigurerAdapter가 deprecate되어 SecurityFilterChain 기반 코드로 변경합니다.
- authorizeHttpRequests 의 자세한 사용 방법은 Spring 기술문서를 참고 바랍니다.
https://docs.spring.io/spring-security/reference/servlet/authorization/authorize-http-requests.html
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
import lombok.RequiredArgsConstructor;
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig {
private final KakaoOAuth2UserService kakaoOAuth2UserService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(withDefaults())
.cors(withDefaults())
.authorizeHttpRequests(request -> request
.requestMatchers("/index.html",
"/images/**",
"/permitAllConents.html")
.permitAll()
.requestMatchers("/user").hasRole("USER")
.anyRequest().authenticated())
.oauth2Login(oauth2 -> oauth2.userInfoEndpoint(userInfo -> userInfo
.userService(kakaoOAuth2UserService)))
.logout(withDefaults());
return http.build();
}
}
▶ KakaoOAuth2UserService.java
package com.example.demo;
import java.util.Collections;
import java.util.Map;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@Service
public class KakaoOAuth2UserService extends DefaultOAuth2UserService {
private final HttpSession httpSession;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
Map<String, Object> attributes = oAuth2User.getAttributes();
log.info("attributes :: " + attributes);
httpSession.setAttribute("login_info", attributes);
return new DefaultOAuth2User(Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")),
oAuth2User.getAttributes(), "id");
}
}
* Spring Security5를 이용하여 카카오 로그인 OAuth2를 구현하기 위한 가장 간단한 소스코드를 위해 많은 부분을 생략 하고 인증 부분만 구현 하였습니다. Spring을 구동하여 http://localhost:8080/login 으로 접근하면 Default 로그인 페이지가 표시됩니다.
* SecurityFilterChain 내 authorizeHttpRequests의 requestMatchers 설정으로 별도 로그인 페이지를 두고 http://localhost:8080/oauth2/authorization/kakao 를 호출하면 스프링을 거쳐 카카오에 인가코드 요청하고 리다이렉트 URI로 돌아와 액세스 토큰 발급 및 사용자 정보조회가지 OAuth2 Client에서 처리합니다.
링크는 application.yml에 정의된 authorization-uri에 다음과 같이 파라메터를 구성하여 세팅됩니다.
kakao에서 로그인 이후 호출된 CallBack URI에서 리턴받은 code를 이용하여 토큰 요청을 하고 받은 토큰을 이용하여 DefaultOAuth2UserService를 상속받은 KakaoOAuth2UserService의 loadUser 함수 호출로 프로필 정보를 조회합니다.
로그인 성공 이후 리다이렉트 페이지를 구성하지 않았지만, loadUser에서 Console 로그 출력으로 프로필을 정상적으로 조회 했음을 확인할 수 있습니다.
'3th Party Util' 카테고리의 다른 글
asp.net core 에서 nuget 라이브러리로 카카오 로그인 (0) | 2022.05.04 |
---|---|
카카오 로그인 (카카오 싱크) 전후 GA 전환 추적 검증 방법 (0) | 2021.09.16 |
카카오 로그인 에러 확인용 크롬 확장 프로그램 (0) | 2021.01.14 |
JavaScript - Kakao Maps JavaScript SDK Wrapper (0) | 2021.01.03 |
JavaScript - Kakao JavaScript SDK Wrapper (0) | 2020.12.31 |
댓글