본문 바로가기

프로젝트

TIL-221205 - 카카오 서드파티 구현하기

오늘은 카카오 서드파티를 구현을 완료했다..

 

어제는 딱 카카오 싱크 페이지까지만 했었는데 오늘은 전체적으로 구현을 완료했다. 

 

 

이렇게 카카오 싱크를 통해 개인정보 수집제공에 동의를 하면 닉네임 정보를 얻어 올 수 있다. 어떻게 얻을 수 있냐 

확인을 누르면 redirect-uri로 설정해놓은 url로 리다이렉트를 시켜주고 쿼리 스트링으로 authCode라는 것을 주는 데 

이곳에 본인이 카카오 서버로 부터 얻을 유저의 정보를 decode해놓은 것이라고 생각하면 된다.

 

 

그러면 redirect-urI로 설정해놓은 페이지로 가서 쿼리파라미터로 붙어 있는 code를 해당 페이지가 마운트 될 떄 

API서버로 요청을 보내 해당 유저의 정보를 들고 올 수 있다. 

 

 

kakaoAuthUtil의 안에있는 process 메소드를 통해서 해당 정보들을 권한 설정을 통해 가져오고 싶은 정보들을 가져 올 수 있다.

 

   @Value("${kakao.api-key}")
    private String apiKey;

    @Value("${kakao.redirect-uri}")
    private String redirectUri;

    private Map<String, String> kakaoUserInformation;

    public KakaoAuthUtil() {
        kakaoUserInformation = new LinkedHashMap<>();
    }

    public SocialLoginProcessResultDto process(String code) {

        String accessToken = getAccessToken(code);

        getDetail(accessToken);

        return new SocialLoginProcessResultDto(
            kakaoUserInformation.get("accessToken"),
            kakaoUserInformation.get("refreshToken"),
            kakaoUserInformation.get("nickname"),
            kakaoUserInformation.get("email"),
            kakaoUserInformation.get("kakaoUserId")
        );
    }

    public String getAccessToken(String code) {
        RestTemplate restTemplate = new RestTemplate();

        // HttpHeader 객체 생성
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.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", apiKey);
        params.add("redirect_uri", redirectUri);
        params.add("code", code);

        // HttpHeader와 HttpBody를 하나의 객체에 담기 -> 만든 이유 : 아래의 exchange 함수에 HttpEntity를 넣어야 해서..
        HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
            new HttpEntity<>(params, httpHeaders); // body 데이터와 headers 값을 가지고 있는 Entity

        // 카카오에게 Http 요청하기 (POST 방식) -> response라는 변수에 응답을 받음

        JsonElement element = JsonParser.parseString(Objects.requireNonNull(restTemplate.exchange(
            "https://kauth.kakao.com/oauth/token",
            HttpMethod.POST,
            kakaoTokenRequest,
            String.class).getBody()));

        String accessToken = element.getAsJsonObject().get("access_token").getAsString();
        String refreshToken = element.getAsJsonObject().get("refresh_token").getAsString();

        kakaoUserInformation.put("accessToken", accessToken);
        kakaoUserInformation.put("refreshToken", refreshToken);

        return accessToken;
    }

    public void getDetail(String accessToken) {
        // 유저정보 요청
        RestTemplate restTemplate = new RestTemplate();

        // HttpHeader

        // HttpHeader와 HttpBody 담기
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + accessToken);
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        // HttpHeader와 HttpBody 담기
        HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest = new HttpEntity<>(headers);

        String response = restTemplate.exchange(
            "https://kapi.kakao.com/v2/user/me",
            HttpMethod.GET,
            kakaoProfileRequest,
            String.class).getBody();

        JsonElement element = JsonParser.parseString(response);

        JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
        JsonObject kakaoAccount = element.getAsJsonObject().get("kakao_account").getAsJsonObject();

        String id = element.getAsJsonObject().get("id").getAsString();
        String nickname = properties.getAsJsonObject().get("nickname").getAsString();
        String email = kakaoAccount.getAsJsonObject().get("email").getAsString();

        kakaoUserInformation.put("kakaoUserId", id);
        kakaoUserInformation.put("nickname", nickname);
        kakaoUserInformation.put("email", email);
    }

 

본인의 api-key나 redirect-uri는 application-properties파일에서 사용을 하면 될 것 같다.(깃에 올라가면 안됨)

 

간단하게 요약을 하면 프론트엔드에서 전달 받았던 code를 통해서 카카오서버에서 accessToken을 받아오고 해당 accessToken을 통해서 정보를 해당 유저의 정보를 받아온 뒤 JSON형태로 변형 해주면 된다.