소셜 로그인 구현
이전 글에서 소셜 로그인 구현을 위한 사전 준비를 하였다.
이제 스프링 부트에서 oauth2-client와 webflux로 소셜 로그인을 구현해볼 것이다.
소셜 로그인 화면은 Provider에서 제공하는거라 딱히 프론트쪽 구현 없이도 테스트 할 수 있다.
아래 그림은 카카오 디벨로퍼스에서 제공하는 카카오 로그인 흐름도이다.
구현 방법에 따라 다르겠지만 우선 본인이 구현한 방법에서는 백엔드에서 생각할 건 아래 두가지이다.
- 리다이렉트 URL로 컨트롤러 호출 시 Provider 이름, 인증 코드 확인
- 서비스 레이어에서 토큰 발급 후 이 토큰으로 유저 정보 받아오기
이번 글에서는 컨트롤러를 호출하고 Provider 이름과 인증 코드를 확인하는 부분까지 진행한다.
사용 기술
- Spring Boot 3.2.4 / gradle-kotlin
- Java 17
- webflux, oauth2-client
1. 프로젝트 사전 작업
1-1. 의존성 추가
아래 두 라이브러리의 의존성을 추가해준다.
webflux는 서버에서 HTTP 요청을 하기 위해서 사용하고, oauth2-client는 소셜 로그인을 구현하기 위해 사용한다.
// build.gradle.kts
// 소셜 로그인
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation ("org.springframework.boot:spring-boot-starter-webflux")
1-2. application.yml 설정
oauth2-client를 사용하기 위해서는 아래처럼 yml 파일을 설정해줘야한다.
아래에서 # 으로 표시한 클라이언트 ID, 시크릿 키, 리다이렉트 URL 외에는 그대로 써도 무방하다.
변경한다면 client-name는 원하는대로 바꿔도 될듯하고, scope도 각자 설정한 부분만큼 설정하면 될 것 같다.
참고로 구글은 provider depth에 없는 이유는 기본적으로 설정이 되어 있어서다.
클라이언트 ID, 시크릿 키를 확인하는 위치는 이전 글을 참고하자.
spring:
security:
oauth2:
client:
registration:
google:
client-id: # 발급 받은 Client ID
client-secret: # 발급 받은 시크릿 키
redirect-uri: http://localhost:8080/api/auth/oauth2/google # 설정한 리다이렉트 URL
scope:
- email
- profile
client-name: 구글
naver:
client-id: # 발급 받은 Client ID
client-secret: # 발급 받은 시크릿 키
client-authentication-method: client_secret_post
authorization-grant-type: authorization_code
redirect-uri: # 설정한 리다이렉트 URL
scope:
- name
- email
- profile_image
client-name: 네이버
kakao:
client-id: # 발급 받은 Client ID
client-secret: # 발급 받은 시크릿 키
client-authentication-method: client_secret_post
authorization-grant-type: authorization_code
scope:
- profile_nickname
- profile_image
- account_email
redirect-uri: # 설정한 리다이렉트 URL
client-name: 카카오
provider:
naver:
authorization-uri: https://nid.naver.com/oauth2.0/authorize
token-uri: https://nid.naver.com/oauth2.0/token
user-info-uri: https://openapi.naver.com/v1/nid/me
user-info-authentication-method: header
user-name-attribute: response # Naver 응답 값 resultCode, message, response 중 response 지정
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-info-authentication-method: header
user-name-attribute: id # Kakao 응답 값 id, connected_at, properties, kakao_account 중 id 지정
2. 컨트롤러 호출 부분
컨트롤러를 호출하는 부분에 대해 설명해보려 한다.
Provider가 기본적으로 제공하는 화면이 있기 때문에 사용자를 그 화면을 호출하는 링크로 이동시키면 된다.
기본적인 형태는 아래와 같다.
{Provider가 제공하는 로그인 화면 주소}
?client_id={클라이언트 ID}
&redirect_uri={리다이렉트 URL}
&response_type=code
아래는 본인이 로컬에서 테스트할 때 사용하는 소셜 로그인 페이지 이동 링크이다.
2-1. 네이버 로그인 주소
기본적인 형태를 따른다.
2-2. 카카오 로그인 주소
기본적인 형태를 따른다.
2-1. 구글 로그인 주소
구글 로그인 시 scope 값에 따라 제공하는 정보가 다르므로 스코프를 추가하고 나머지는 기본적인 형태를 따른다.
3. 컨트롤러 구현
리다이렉트 URL로 컨트롤러를 호출하므로 GET 요청을 받는다.
또한 하나의 컨트롤러로 여러개의 Provider를 받기 위해 아래처럼 PathVariable로 다형적으로 받도록 설정했다.
또한 인증 코드는 Provider에서 리다이렉트 시 code라는 키 값의 쿼리 스트링으로 주므로 아래처럼 받았다.
소셜 로그인을 진행하고 성공 시 JWT를 쿠키에 담아 반환한다.
그리고 요청을 받는게 백엔드쪽 주소이므로 프론트 URL로 리다이렉트 시켜줬다.
AuthController
@Operation(summary = "소셜 로그인", description = "소셜 로그인 성공 시 쿠키를 반환합니다.")
@ApiResponse(responseCode = "200", description = "로그인에 성공",
headers = {
@Header(name = "Set-Cookie", description = "인증 쿠키")
})
@ApiResponse(responseCode = "400", description = "잘못된 아이디 혹은 비밀번호")
@GetMapping("/oauth2/{provider}")
public ResponseEntity<ApiMessageResponse> oauth2Login(@PathVariable String provider, @RequestParam String code) {
String jwtCookie = authFacade.oauth2Login(code, provider);
return ResponseEntity
.status(HttpStatus.FOUND)
.header(HttpHeaders.SET_COOKIE, jwtCookie)
.header(HttpHeaders.LOCATION, appConfig.getFrontDeployUrl())
.body(new ApiMessageResponse("소셜 로그인에 성공했습니다."));
}
'API 만들어 보기 > 소셜 로그인' 카테고리의 다른 글
소셜 로그인 3: 서비스 레이어 구현 (0) | 2024.05.10 |
---|---|
소셜 로그인 1: 사전 작업 (0) | 2024.05.08 |