0. 전체 Flow
오늘은 Step 3 부분을 구현해보고자 한다.
① Access Token을 이용하여 Kakao Auth Server에게 사용자 정보 요청
② 사용자 정보 받기
1. OAuthService 구현
♠ Kakao Developers Docs
우리는 결국 https://kauth.kakao.com/oauth/token 으로 POST 요청을 보내서 사용자 정보를 받으면 된다.
카카오 공식 문서에 request, response와 관련된 형식이 안내되어 있다.
▷ 꺼내올 데이터
RESPONSE의 id 데이터
RESPONSE의 properties에 담긴 nickname 데이터
RESPONSE의 kakao_account에 담긴 email 데이터
나는 어떤 분의 블로그 글을 참고하여 코드를 작성 및 공부하였다.
( 출처 https://suyeoniii.tistory.com/81 )
전체 코드를 한번 훑어보고, 하나하나 뜯어보며 이해해보자.
// OAuthService.java
package com.surveasy.surveasy.service;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.springframework.stereotype.Service;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
@Service
public class OAuthService {
public String getKakaoAccessToken(String code) {
String access_Token = "";
String refresh_Token = "";
String reqURL = "https://kauth.kakao.com/oauth/token";
try {
// 지난번에 작성했던 Access Token 발급 함수
} catch (IOException e) {
e.printStackTrace();
}
return access_Token;
}
public HashMap<String, Object> createKakaoUser(String token) {
HashMap<String, Object> userInfo = new HashMap<String, Object>();
String reqURL = "https://kapi.kakao.com/v2/user/me";
try {
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Bearer " + token); // header 작성, access token 전달
// 결과 코드가 200이면 성공
int responseCode = conn.getResponseCode();
System.out.println("response CODE : " + responseCode);
// 요청을 통해 얻은 JSON 타입의 Response 데이터 읽어오기
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null) {
result += line;
}
System.out.println("response BODY : " + result);
// GSON 라이브러리로 JSON 파싱
JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(result);
JsonObject properties = jsonElement.getAsJsonObject().get("properties").getAsJsonObject();
JsonObject kakao_account = jsonElement.getAsJsonObject().get("kakao_account").getAsJsonObject();
int id = jsonElement.getAsJsonObject().get("id").getAsInt();
boolean hasEmail = kakao_account.get("has_email").getAsBoolean();
String nickname = properties.getAsJsonObject().get("nickname").getAsString();
userInfo.put("nickname", nickname);
String email = "";
if(hasEmail) {
email = kakao_account.get("email").getAsString();
userInfo.put("email", email);
}
System.out.println("id : " + id);
System.out.println("email : " + email);
System.out.println("nickname : " + nickname);
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return userInfo;
}
}
1-1. 변수 설정
우리가 받아올 nickname, email을 담을 해시맵 userInfo를 초기화 하고, 요청을 보낼 request URI 주소도 정의해놓는다.
HashMap<String, Object> userInfo = new HashMap<String, Object>();
String reqURL = "https://kapi.kakao.com/v2/user/me";
1-2. http connection 열기
2-1에서 정의한 reqest URI에 POST 요청을 보내기 위해 http connection을 정의하고,
사용을 위해 스위치를 켜준다. (setDoOutput 값을 false → true로 변경)
이때, 헤더에는 다양한 인증 타입을 가진 토큰들 중 어떤 종류인지를 알려주는 정보를 담아서 보내야 한다.
우리가 사용할 토큰 타입은 Bearer로, JWT 혹은 OAuth와 관련된 토큰 종류라고 한다.
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Bearer " + token); // header 작성, access token 전달
// 결과 코드가 200이면 성공
int responseCode = conn.getResponseCode();
System.out.println("response CODE : " + responseCode);
1-3. 요청 결과를 JSON 타입으로 읽어오기
stream으로 받아온 string 데이터들을 gson 라이브러리를 통해 JSON Object 형태로 파싱한다.
// 요청을 통해 얻은 JSON 타입의 Response 데이터 읽어오기
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null) {
result += line;
}
System.out.println("response BODY : " + result);
// GSON 라이브러리로 JSON 파싱
JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(result);
1-4. id , nickname , email 꺼내기
1-3에서 만들어낸 object에서 id, nickname, email을 꺼낸다.
이때, 사용한 bufferedReader, bufferedWriter는 close 해준다.
JsonObject properties = jsonElement.getAsJsonObject().get("properties").getAsJsonObject();
JsonObject kakao_account = jsonElement.getAsJsonObject().get("kakao_account").getAsJsonObject();
int id = jsonElement.getAsJsonObject().get("id").getAsInt();
boolean hasEmail = kakao_account.get("has_email").getAsBoolean();
String nickname = properties.getAsJsonObject().get("nickname").getAsString();
userInfo.put("nickname", nickname);
String email = "";
if(hasEmail) {
email = kakao_account.get("email").getAsString();
userInfo.put("email", email);
}
System.out.println("id : " + id);
System.out.println("email : " + email);
System.out.println("nickname : " + nickname);
bufferedReader.close();
2. OAuthController에서 결과 확인
OAuthController에서 userInfo 해시맵을 완성하고, 결과를 확인해보자!
// OAuthController.java
package com.surveasy.surveasy.controller;
import com.surveasy.surveasy.service.OAuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@RestController
@RequiredArgsConstructor
public class OAuthController {
private final OAuthService oAuthService;
@ResponseBody
@GetMapping("/kakao")
public void kakaoCallBack(@RequestParam String code) {
String access_Token = oAuthService.getKakaoAccessToken(code);
// System.out.println(access_Token);
HashMap<String, Object> userInfo = oAuthService.createKakaoUser(access_Token);
System.out.println(userInfo);
}
}
RUN하고 프론트를 통해 카카오 로그인을 해본 결과, 이메일과 닉네임을 잘 받아온 것을 확인할 수 있다 !
'Spring > Spring Boot' 카테고리의 다른 글
[Spring boot - OAuth2] Google Login 구현 #1 (0) | 2023.02.02 |
---|---|
[Spring Boot | 삽질] H2 Database (User Table) (0) | 2023.01.20 |
[Spring boot - OAuth2] Kakao Login 구현 #03 (0) | 2022.11.18 |
[Spring boot - OAuth2] Kakao Login 구현 #02 (0) | 2022.11.17 |
[Spring boot - OAuth2] Kakao Login 구현 #01 (0) | 2022.11.12 |