본문 바로가기

Web/Spring boot

spring boot 소셜 카카오 로그인 로그아웃

*KakaoOAuth2

package com.spring.security.security.kakao;

import com.spring.security.security.kakao.KakaoUserInfo;
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. 인가코드를 엑세스토큰으로
        String accessToken = getAccessToken(authorizedCode);
        // 2. 액세스토큰을 카카오 사용자 정보로 
KakaoUserInfo userInfo = getUserInfoByToken(accessToken);
        return userInfo;
    }

    private String getAccessToken(String authorizedCode){
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("grant_type", "authorization_code");
        params.add("redirect_uri", "http://localhost:8080/user/kakao/callback");
        params.add("code", authorizedCode);
        params.add("client_id", "1d6d5f399397c1c9d43c437b16a4c4e8");

        RestTemplate rt = new RestTemplate();
        HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest = new HttpEntity<>(params, headers);

        ResponseEntity<String> response = rt.exchange(
                "https://kauth.kakao.com/oauth/token",
                HttpMethod.POST,
                kakaoTokenRequest,
                String.class
        );

        String tokenJson = response.getBody();
        JSONObject rjson = new JSONObject(tokenJson);
        String accessToken = rjson.getString("access_token");
        return accessToken;
    }

    private KakaoUserInfo getUserInfoByToken(String accessToken) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + accessToken);
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        RestTemplate rt = new RestTemplate();
        HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest = new HttpEntity<>(headers);

        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);
    }
}

 

KakaoOAuth2 클래스 메소드 별 세부 설명

 

 

>public KakaoUserInfo getUserInfo(String authorizedCode) 메소드:

public KakaoUserInfo getUserInfo(String authorizedCode) {
//authorizedCode(서버로부터 받은 인가코드)에서 엑세스 토큰 추출
    String accessToken = getAccessToken(authorizedCode);
// 엑세스 토큰에서 User정보(KakaoUserInfo)를 추출
    KakaoUserInfo userInfo = getUserInfoByToken(accessToken);
    return userInfo;
}

 

 

>private String getAccessToken(String authorizedCode) 메소드 :

인가코드에서 엑세스 토큰 추출하는 메소드

private String getAccessToken(String authorizedCode){
//Http 헤더 생성
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
    //Http 바디 생성
    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    params.add("grant_type", "authorization_code");
    params.add("redirect_uri", "http://localhost:8080/user/kakao/callback");
    params.add("code", authorizedCode);
    params.add("client_id", "1d6d5f399397c1c9d43c437b16a4c4e8");
    //Http방식으로 Rest API 호출 이후 응답이 올때까지 대기하는 동기 방식
    RestTemplate rt = new RestTemplate();
//위에서 생성한 Http 헤더와 바디를 하나의 Http엔티티로 만들어서 kakao에 토큰요청
    HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest = new HttpEntity<>(params, headers);
    //다음 url에 post방식으로 토큰 요청, 그에 대한 응답 엔티티
    ResponseEntity<String> response = rt.exchange(
            "https://kauth.kakao.com/oauth/token",
            HttpMethod.POST,
            kakaoTokenRequest,
            String.class
    );
    //응답 엔티티의 바디를 JSON 형식으로 바꾸어 access_token 추출
    String tokenJson = response.getBody();
    JSONObject rjson = new JSONObject(tokenJson);
    String accessToken = rjson.getString("access_token");
    return accessToken;
}

 

>private KakaoUserInfo getUserInfoByToken(String accessToken) :

엑세스 토큰에서 kakao user 정보 추출

private KakaoUserInfo getUserInfoByToken(String accessToken) {
//Http 헤더 생성
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Bearer " + accessToken);
    headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
  
    RestTemplate rt = new RestTemplate();
//토큰을 가지고 서버에 kakao profile을 요청하기 위해 Http엔티티 생성
    HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest = new HttpEntity<>(headers);

    ResponseEntity<String> response = rt.exchange(
            "https://kapi.kakao.com/v2/user/me",
            HttpMethod.POST,
            kakaoProfileRequest,
            String.class
    );
    //요청에 대한 응답에서 id,email,nickname 추출
    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);
}

 

 

*KakaoUserInfo

package com.spring.security.security.kakao;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class KakaoUserInfo {
    Long id;
    String email;
    String nickname;
}

'Web > Spring boot' 카테고리의 다른 글

spring security 로그인 로그아웃 회원가입  (0) 2022.01.09