내가 애플리케이션 등록을 통해 받은 REST KEY로 인증코드 요청 -> 전달받음
사용자가 카카오로그인페이지를 통해 '동의하고 계속하기' 누르면 미리 설정해둔 (카카오 디벨로퍼) Redirect URI (callback)로 인가토큰이 전달된다
usercontroller 에서 Redirect URI (callback)를 통해 인가토큰 받고 userService 호출 => userService의 kakaologin 메소드에서 kakaoOAuth를 호출해서 애플리케이션이 사용자의 정보에 접근하도록 허용한다 => 카카오로그인 후 회원정보가 userRepository에 저장
✔ KakaoOAuth2
package com.sparta.springcore.security.kakao;
import org.json.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
@Component
public class KakaoOAuth2 {
public KakaoUserInfo getUserInfo(String authorizedCode) {
// 1. 인가코드 -> 액세스 토큰
// authorizedCode: 카카오 서버로부터 받은 인가 코드
String accessToken = getAccessToken(authorizedCode);
// 2. 액세스 토큰 -> 카카오 사용자 정보에 접근
KakaoUserInfo userInfo = getUserInfoByToken(accessToken);
return userInfo;
}
private String getAccessToken(String authorizedCode) {
// HttpHeader 오브젝트 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HttpBody 오브젝트 생성
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "*{본인의 REST API키}*");
params.add("redirect_uri", "http://localhost:8080/user/kakao/callback");
params.add("code", authorizedCode);
// HttpHeader와 HttpBody를 하나의 오브젝트에 담기
RestTemplate rt = new RestTemplate();
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
new HttpEntity<>(params, headers);
// Http 요청하기 - Post방식으로 - 그리고 response 변수의 응답 받음.
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token",
HttpMethod.POST,
kakaoTokenRequest,
String.class
);
// JSON -> 액세스 토큰 파싱
String tokenJson = response.getBody();
JSONObject rjson = new JSONObject(tokenJson);
String accessToken = rjson.getString("access_token");
return accessToken;
}
private KakaoUserInfo getUserInfoByToken(String accessToken) {
// HttpHeader 오브젝트 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + accessToken);
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HttpHeader와 HttpBody를 하나의 오브젝트에 담기
RestTemplate rt = new RestTemplate();
HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest = new HttpEntity<>(headers);
// Http 요청하기 - Post방식으로 - 그리고 response 변수의 응답 받음.
ResponseEntity<String> response = rt.exchange(
"https://kapi.kakao.com/v2/user/me",
HttpMethod.POST,
kakaoProfileRequest,
String.class
);
JSONObject body = new JSONObject(response.getBody());
Long id = body.getLong("id");
String email = body.getJSONObject("kakao_account").getString("email");
String nickname = body.getJSONObject("properties").getString("nickname");
return new KakaoUserInfo(id, email, nickname);
}
}