2024. 5. 10. 16:37ㆍFull Stack Course 풀스택과정/SPRING
배울내용:
OAuth2 실행테스트
OAuth2 구글 로그인
스프링부트 OAuth2
SpringBoot OAuth2
카카오 로그인 만들기
kakao 로그인
카카오 로그인 연동
액세스 토큰 만들기
인증 관련 설정값
OAuth 뷰 구성
이번 포스팅을 Springboot로 카카오로 인증로그인 해볼것이다
만약 추가적으로 구글 로그인이 하고싶으면 아래의 링크로 가자
https://sarimus.tistory.com/123
SpringBoot - OAuth2 로 구글 로그인 (1) (토큰 발급받기)
배울내용: SpringBoot - OAuth2 OAuth2 로 구글 로그인 스프링부트 토큰 발급받기 구글 클라우드 콘솔 OAuth 서비스 구현하기 구글 로그인 만들기 스프링 부트 구글로그인 연동 스프링 부트 구글 로그인
sarimus.tistory.com
먼저 카카오 developer 에서 설정하는것은 아래의 것처럼 가보자
필자도 아래의 블로그를 참고해서 했다 (아래블로그도 어느정도 되나 버전이 바뀌면서 안되는 케이스로 바뀜)
https://velog.io/@zhyun/spring-boot-OAuth-2-kakao-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%B0%EB%8F%99
Spring Boot: OAuth2 kakao 로그인 연동
kakao 🍫
velog.io
[출저 - 2303100353-231116.log ]
2. Spring Boot 에서 설정
1. OAuth2 Client Dependency 추가
외부 서비스에서 OAuth 인증을 받아 사용하려는 것이기 때문에
새로운 프로젝트를 만들때 Spring Initializer에서 OAuth2 Client 를 추가해준다.
버전참고
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.4'
}
또는 그냥 build.gradle 에 dependency 를 아래처럼 추가해주면 된다
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
2. appication.yml 설정 파일 작성
위에 블로그 포스팅에서는 아래처럼 나와 있다
spring:
security:
oauth2:
client:
registration:
kakao:
client-id: ${kakao.client.id} # 앱키 -> REST API 키
client-secret: ${kakao.client.secret} # 카카오 로그인 -> 보안 -> Client Secret 코드
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/kakao" # yml 파일에서 {} 가 spring 특수문자로 인식되게 하기 위해 " " 사용
client-authentication-method: POST
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 # 식별자 . 카카오의 경우 "id" 사용
그러나 아마 저대로 실행하면 서버에러 500 뜰것이다
그래서 아래처럼 써줘야한다
spring:
security:
oauth2:
client:
registration:
kakao:
client-id: 아까 카카오 dev 받은 내 REST API 키
client-secret: Client Secret 코드
redirect-uri: "http://localhost:8080/login/oauth2/code/kakao"
client-authentication-method: client_secret_post
authorization-grant-type: authorization_code
scope: account_email #동의 항목
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
차이점이 있다면 provider 가 "-" 에서 "_" 으로 바뀌였고 client-authentication-method 가 POST 방식이 아닌
authrozation_code 으로 바뀌었다
그리고또한 기존에 config 코드에 6.1 버전이하로는 안된다고 deprecated 되었다고 되있으면서 csrf 나 disable 그리고 service 부분에서 빨간줄로 밑줄그여있을것이다
이부분을 "람다식" 으로 바꿔주면 다해결된다
1. 의존성 삽입 ( build.gradle)
아래처럼 딱 카카오 로그인에 필요한 것들만 만들었다
먼저 Oauth2 를 사용할 Dependency 와 그외에 dependency 를 build.gradle 에 아래처럼 넣어주자
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.codehows'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
2. 실행시켜줄 html 화면 만들기
먼저 실행시켜줄 화면을 만들어준다
template 패키지에 login.html 을 만들어주고 아래처럼 만들어준다
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/oauth2/authorization/kakao">카카오 로그인</a>
</body>
</html>
3. 로그인 Controller 구현
카카오 로그인 요청 시 인가 코드 받기, 토큰 받기, 사용자 로그인 처리의 과정을 수행할 Controller 코드를 작성한다.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/login")
public class LoginController {
@GetMapping
public String login(){
return "login";
}
}
4. 사용자 인증을 처리 (Service 구현 )
이 코드는 Spring Security 및 OAuth2를 사용하여 사용자 인증을 처리하는 서비스 클래스를 정의
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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 java.util.List;
@Service
public class OAuth2UserService extends DefaultOAuth2UserService {
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
// Role generate
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ADMIN");
// nameAttributeKey
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails()
.getUserInfoEndpoint()
.getUserNameAttributeName();
// DB 저장로직이 필요하면 추가
return new DefaultOAuth2User(authorities, oAuth2User.getAttributes(), userNameAttributeName);
}
}
5. Spring Security를 사용하여 OAuth2 로그인을 구성 (Config 구현)
이 코드는 Spring Security를 사용하여 OAuth2 로그인을 구성하고, 로그인 성공 시 원하는 동작을 수행하는 데 사용된다. 예를 들어, 사용자의 인증 정보를 기반으로 사용자 정보를 응답하거나, 세션을 설정하거나 다양한 작업을 수행할 수 있다.
아마 이부분에서 다들 오류가 뜨는데 람다식으로
.csrf((csrf) ->
csrf.disable()
);
이런식으로 바꿔주면 작동할것이다
import com.codehows.animalcafe.service.OAuth2UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
private final OAuth2UserService oAuth2UserService;
public SecurityConfig(OAuth2UserService oAuth2UserService) {
this.oAuth2UserService = oAuth2UserService;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf((csrf) ->
csrf.disable()
);
http.authorizeHttpRequests(config -> config.anyRequest().permitAll());
http.oauth2Login(oauth2Configurer -> oauth2Configurer
.loginPage("/login")
.successHandler(successHandler())
.userInfoEndpoint(userInfo -> userInfo
.userService(oAuth2UserService)));
return http.build();
}
@Bean
public AuthenticationSuccessHandler successHandler() {
return ((request, response, authentication) -> {
DefaultOAuth2User defaultOAuth2User = (DefaultOAuth2User) authentication.getPrincipal();
String id = defaultOAuth2User.getAttributes().get("id").toString();
String body = """
{"id":"%s"}
""".formatted(id);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
PrintWriter writer = response.getWriter();
writer.println(body);
writer.flush();
});
}
}
5. 로그인 시도해보기
먼저 아까 만들것들을 메인에서 실행한뒤에
controller 에서 만든 login 을 localhost:8080/+ login 을 해주면 아래처럼 보이게된다
이 카카오 로그인을 클릭하게 되면
카카오 로그인창이 뜨고
만약 이런창이 안나오면 제대로 된게 아니다
그리고 이렇게 2단계 인증을 하라고 하면 카카오톡에서
이렇게 인증메세지를 보내준다 (필자는 영어공부한다고 언어를 영어로 바꿔서 이렇게 나오지만 한글로 되어있으면 한글로 나옴)
그리고 인증이 완료 되면 아래처럼 보이게된다
이렇게 되면 성공적으로 카카오 로그인 연동을 성공한 것이다
그리고 만약 Id 뿐만아니라 다른 email 을 원하면
@Bean
public AuthenticationSuccessHandler successHandler() {
return ((request, response, authentication) -> {
DefaultOAuth2User defaultOAuth2User = (DefaultOAuth2User) authentication.getPrincipal();
String id = defaultOAuth2User.getAttributes().get("id").toString();
String body = """
{"id":"%s"}
""".formatted(id);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
PrintWriter writer = response.getWriter();
writer.println(body);
writer.flush();
});
}
이부분에서 추가해주면 더받을수 있을것이다.
'Full Stack Course 풀스택과정 > SPRING' 카테고리의 다른 글
Springboot 상세검색 , 조건검색 및 페이징 (0) | 2024.05.22 |
---|---|
SpringBoot - OAuth2 로 카카오 로그인 (2) DB저장,메인화면이동, 로그아웃(세션종료) 추가 (0) | 2024.05.14 |
스프링부트 비동기식 방명록 만들기 ( 2 ) (0) | 2024.05.06 |
스프링부트 비동기식 방명록 만들기 ( 1 ) (0) | 2024.05.06 |
SpringBoot - TOAST UI Editor 로 게시글 사진 업로드 (0) | 2024.04.24 |