본문 바로가기
Spring

[Spring] REST 방식으로 카카오 로그인 구현하기 - 2

by 태진아밴드 2020. 10. 5.

이전에 썼던 카카오 로그인 구현하기를 이어써본다.

 

먼저 카카오개발자내의 REST API 문서를 다시 살펴보자.

 

* URL

POST /oauth/token HTTP/1.1
Host: kauth.kakao.com
Content-type: application/x-www-form-urlencoded;charset=utf-8

* Parameter

Name Type Description Required
grant_type String "authorization_code"로 고정 O
client_id String 앱 생성 시 발급 받은 REST API O
redirect_uri String 인증 코드가 리다이렉트된 URI O
code String 인증 코드 받기 요청으로 얻은 인증 코드 O
client_secret String 토큰 발급 시, 보안을 강화하기 위해 추가 확인하는 코드
[내 애플리케이션] > [보안]에서 설정 가능
ON 상태인 경우 필수 설정해야 함
X

* Response

Key

Name Type Description
token_type String 토큰 타입, "bearer"로 고정
access_token String 사용자 액세스 토큰 값
expires_in Integer 액세스 토큰 만료 시간(초)
refresh_token String 사용자 리프레시 토큰 값
refresh_token_expires_in Integer 리프레시 토큰 만료 시간(초)
scope String 인증된 사용자의 정보 조회 권한 범위
범위가 여러 개일 경우, 공백으로 구분

인증코드를 받은이후 사용자 토큰을 받기위해 호출해야하는 부분이다.

 

우리가 필요한건 응답부분의 access_token 이므로 이런식으로 구현해주자. 

 

* java

getAccessToken 부분

// 카카오 로그인 access_token 리턴
public String getAccessToken(HttpServletRequest request, String code) throws Exception {

    String accessToken = "";

    // restTemplate을 사용하여 API 호출
    RestTemplate restTemplate = new RestTemplate();
    String reqUrl = "/oauth/token";
    URI uri = URI.create(kakaoAuthUrl + reqUrl);

    HttpHeaders headers = new HttpHeaders();

    MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<String, Object>();
    parameters.set("grant_type", "authorization_code");
    parameters.set("client_id", kakaoApiKey);
    parameters.set("redirect_uri", redirectURI + "/login/oauth_kakao");
    parameters.set("code", code);

    HttpEntity<MultiValueMap<String, Object>> restRequest = new HttpEntity<>(parameters, headers);
    ResponseEntity<JSONObject> apiResponse = restTemplate.postForEntity(uri, restRequest, JSONObject.class);
    JSONObject responseBody = apiResponse.getBody();

    accessToken = (String) responseBody.get("access_token");

    return accessToken;
}

마찬가지로 properties에 별도로 변수로 잡아둔 kakaoApiKey, redirectURI 를 넣어주고 restTemplate을 사용하여 API를 호출해준다.

 

이후 응답받은 부분에서 accessToken를 추출한 뒤 리턴해준다.

 

이제 사용자 토큰을 이용해 사용자 고유 번호를 추출하기 위해 사용자 정보 가져오는 부분을 살펴보자.

 

* URL

GET/POST /v2/user/me HTTP/1.1
Host: kapi.kakao.com
Authorization: Bearer {USER_ACCESS_TOKEN}
Content-type: application/x-www-form-urlencoded;charset=utf-8

* Header

Name Description Required
Authorization 헤더 포맷
Authorization: Bearer {USER_ACCESS_TOKEN}
O

* Additional Parameter

Key Type Description
secure_resource Boolean 이미지 URL 값 HTTPS 여부, true 설정 시 HTTPS 사용, 기본 값 false
property_keys JSON[] Property 키 목록, JSON Array를 ["properties.nickname"]과 같은 형식으로 사용

파라미터 없이 호출할경우 로그인 아이디 및 닉네임이 나오게 되지만 우리에게 필요한건 사용자 고유 번호 이므로 파라미터를 추가해서 호출해주자.

 

* java

getKakaoUniqueNo 부분

// 카카오 사용자 id 추출
public String getKakaoUniqueNo(String accessToken) throws Exception {

    String kakaoUniqueNo = "";

    // restTemplate을 사용하여 API 호출
    RestTemplate restTemplate = new RestTemplate();
    String reqUrl = "/v2/user/me";
    URI uri = URI.create(kakaoApiUrl + reqUrl);

    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", "bearer " + accessToken);
    headers.set("KakaoAK", kakaoApiKey);

    MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<String, Object>();
    parameters.add("property_keys", "[\"id\"]");

    HttpEntity<MultiValueMap<String, Object>> restRequest = new HttpEntity<>(parameters, headers);
    ResponseEntity<JSONObject> apiResponse = restTemplate.postForEntity(uri, restRequest, JSONObject.class);
    JSONObject responseBody = apiResponse.getBody();

    kakaoUniqueNo = Integer.toString(responseBody.getInt("id"));

    return kakaoUniqueNo;

}

뭔가 설명하는 순서가 뒤바뀐거 같지만 아무튼 이렇게 리턴받은 kakaoUniqueNo를 가지고

 

회원테이블을 조회해 로그인 처리를 구현하면 되겠다!

 

다음번에는 카카오 로그인 말고 네이버 로그인 구현과정을 포스팅해봐야겠다.