이어서 빠르게 Naver 소셜 로그인을 구현하려고 한다.
Naver 소셜 로그인도 동일하게 Google 때 구현해놓았던 틀을 기반으로 아주 간단하게 추가하므로 기반 코드가 없다면 아래 포스팅을 참고하면 좋겠다.
[SpringBoot] Google 소셜 로그인 구현: OAuth2.0 & Spring Security 활용
코드 구현에 앞서, 소셜 로그인 개념은 아래 포스팅을 참고하면 좋겠다. Spring Security & OAuth2.0 & JWT Token 소셜로그인 개념 정리Spring Security 란?Spring Security는 애플리케이션의 보안을 담당하는 프레
seung-yo.tistory.com
폴더 구조
동일하게 이전 포스팅을 따라 틀을 갖춰 놓았다면 따로 추가할 필요가 없다. NaverOauth.java, application.properties 파일만 수정할 예정이다.
소셜 로그인 요청 Redirect 처리 (Naver)
- NaverOauth 클래스 수정
NaverOauth.java
package com.example.Profee.service.social;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
// 공통 interface를 구현할 소셜 로그인 각 타입별 Class 생성 (Naver)
@Component
@RequiredArgsConstructor
public class NaverOauth implements SocialOauth {
@Value("${sns.naver.url}")
private String NAVER_SNS_BASE_URL;
@Value("${sns.naver.client.id}")
private String NAVER_SNS_CLIENT_ID;
@Value("${sns.naver.callback.url}")
private String NAVER_SNS_CALLBACK_URL;
@Value("${sns.naver.client.secret}")
private String NAVER_SNS_CLIENT_SECRET;
@Value("${sns.naver.token.url}")
private String NAVER_SNS_TOKEN_BASE_URL;
@Override
public String getOauthRedirectURL() {
Map<String, Object> params = new HashMap<>();
params.put("response_type", "code");
params.put("client_id", NAVER_SNS_CLIENT_ID);
params.put("redirect_uri", NAVER_SNS_CALLBACK_URL);
params.put("state", "random_state_string"); // CSRF 방지를 위한 state 값 추가
String parameterString = params.entrySet().stream()
.map(x -> x.getKey() + "=" + x.getValue())
.collect(Collectors.joining("&"));
return NAVER_SNS_BASE_URL + "?" + parameterString;
}
@Override
public String requestAccessToken(String code) {
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> params = new HashMap<>();
params.put("code", code);
params.put("client_id", NAVER_SNS_CLIENT_ID);
params.put("client_secret", NAVER_SNS_CLIENT_SECRET);
params.put("redirect_uri", NAVER_SNS_CALLBACK_URL);
params.put("grant_type", "authorization_code");
params.put("state", "random_state_string"); // 앞서 전송한 state 값과 일치해야 함
ResponseEntity<String> responseEntity =
restTemplate.postForEntity(NAVER_SNS_TOKEN_BASE_URL, params, String.class);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
// 콘솔에 받은 토큰 출력
String tokenResponse = responseEntity.getBody();
System.out.println("Received Access Token: " + tokenResponse);
return responseEntity.getBody();
}
return "네이버 로그인 요청 처리 실패";
}
public String requestAccessTokenUsingURL(String code) {
try {
URL url = new URL(NAVER_SNS_TOKEN_BASE_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setDoOutput(true);
Map<String, Object> params = new HashMap<>();
params.put("code", code);
params.put("client_id", NAVER_SNS_CLIENT_ID);
params.put("client_secret", NAVER_SNS_CLIENT_SECRET);
params.put("redirect_uri", NAVER_SNS_CALLBACK_URL);
params.put("grant_type", "authorization_code");
params.put("state", "random_state_string");
String parameterString = params.entrySet().stream()
.map(x -> x.getKey() + "=" + x.getValue())
.collect(Collectors.joining("&"));
BufferedOutputStream bous = new BufferedOutputStream(conn.getOutputStream());
bous.write(parameterString.getBytes());
bous.flush();
bous.close();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
if (conn.getResponseCode() == 200) {
// 콘솔에 받은 토큰 출력
String tokenResponse = sb.toString();
System.out.println("Received Access Token: " + tokenResponse);
return tokenResponse;
}
return "네이버 로그인 요청 처리 실패";
} catch (IOException e) {
throw new IllegalArgumentException("알 수 없는 네이버 로그인 Access Token 요청 URL 입니다 :: " + NAVER_SNS_TOKEN_BASE_URL);
}
}
}
application.properties 파일 설정
동일하게 Naver를 통해 발급받은 클라이언트 아이디와 시크릿을 입력해주면 된다.
application.properties
# Google
sns.google.url=https://accounts.google.com/o/oauth2/v2/auth
sns.google.client.id=구글 클라이언트 아이디
sns.google.client.secret=구글 클라이언트 시크릿
sns.google.callback.url=http://localhost:8080/auth/google/callback
sns.google.token.url=https://oauth2.googleapis.com/token
# Kakao
sns.kakao.url=https://kauth.kakao.com/oauth/authorize
sns.kakao.client.id=카카오 클라이언트 아이디
sns.kakao.client.secret=카카오 클라이언트 시크릿
sns.kakao.callback.url=http://localhost:8080/auth/kakao/callback
sns.kakao.token.url=https://kauth.kakao.com/oauth/token
# Naver
sns.naver.url=https://nid.naver.com/oauth2.0/authorize
sns.naver.client.id=네이버 클라이언트 아이디
sns.naver.client.secret=네이버 클라이언트 시크릿
sns.naver.callback.url=http://localhost:8080/auth/naver/callback
sns.naver.token.url=https://nid.naver.com/oauth2.0/token
이후 Spring Boot 서버를 구동시킨 다음 http://localhost:8080/auth/naver 로 들어가면 네이버 소셜 로그인이 잘 되는것을 확인할 수 있다. 😉
'프로젝트 > Profee' 카테고리의 다른 글
[RN] Error resolving plugin [id: 'com.facebook.react.settings'] 오류 해결 (0) | 2024.10.14 |
---|---|
[RN] 안드로이드 에뮬레이터 까만 화면만 나올 때 (0) | 2024.10.14 |
[SpringBoot] Kakao 소셜 로그인 구현: OAuth2.0 & Spring Security 활용 (0) | 2024.09.11 |
[SpringBoot] 400 오류: redirect_uri_mismatch 오류 해결 (0) | 2024.09.10 |
[SpringBoot] Google 소셜 로그인 구현: OAuth2.0 & Spring Security 활용 (0) | 2024.09.10 |