본문 바로가기
스프링

[KaKaoLogin RestAPI] oAuth2.0 + SpringBoot - (1)

by DarrenH 2022. 8. 19.
반응형

오늘은 카카오톡을 이용한 SNS로그인을 하려고합니다. 먼저 카카오톡 개발자센터에서 어플리케이션을 등록해주어야합니다.
https://developers.kakao.com/

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

여기로 가셔서 로그인해주세요

그 다음 내 애플리케이션을 선택 해주세요.

지금 테스트하실 홈페이지의 URL을 적어주시고 저장을 눌러주세요
저는 Localhost_Test로 만들었습니다.

그럼 이 페이지를 마주하게 되시는데요 저희가 사용할 건 RESTAPI 입니다.

그리고 카카오 로그인에 들어가셔서 모두 활성화 해주신다음에 Redirect URI를 설정해주세요.

이때 어떤 주소를 적냐면 카카오 로그인이 끝나고나서 수행할 API주소를 적어주시면 됩니다.
저의 경우 http://localhost:8080/kakao 로 지정했습니다.

이제 동의 항목을 선택해주실건데요 카카오 로그인의 경우 정보를 수집할 항목을 선택할 수 있습니다. 기본적으로 고유한 ID토큰값은 주지만 추가로 더 정보를 가지고올 수 있습니다. 저는 Email을 추가로 수집하겠습니다.

이제 어느정도 준비는 끝났습니다.

이제 값을 전달해주면 끝입니다.

먼저 카카오 공식문서를 한번씩 봐주세요.

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

보시면 어떤 URL로 접근하면 무슨 값을 주는지 알 수 있습니다.
먼저 "/oauth/authorize"를 살펴보겠습니다.

https://kauth.kakao.com/oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code

이런식으로 아까 받았던 RestApi KEY값과 설정해주었던 ReDirectUri를 적어주시면 됩니다.
그리고 Spring에서는 서버를 켜주세요 그리고 해당 URL로 접속을 해주세요.

그럼 이제 다음과 같은 화면을 볼 수 있는데요 로그인을 해줍니다.


그럼 이런 동의 화면이뜨는데 저는 이전에 이미 동의해서 안떠서 미리보기페이지에서 가지고왔습니다.

전체 동의후 계속 눌러주시면 주소창에 보시면 ?code={code}하고 값이 나온 것을 볼 수 있는데요 이 코드를 가지고 AccessToken을 발급받을 겁니다.

포스트맨으로 먼저 실습하겠습니다.
해당 코드를 가지고 복사해주세요.

이렇게 URL을 적어주시고 POST방식으로 보내면 AccessToken과 RefreshToken을 받아옵니다.
이것도 마찬가지로 공식API홈페이지에 보시면 됩니다.

이렇게 사용방법이 나와있습니다.

이거를 코드로 작성해보겠습니다.
먼저 UserController 부터 보겠습니다.

package com.Controller;

import com.Service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

@AllArgsConstructor
@RestController
public class UsersController {

    private UserService userService;

    @PostMapping("/test")
    public String test(){
        return "<h1>test Page</h1>";
    }

    @ResponseBody
    @GetMapping("/kakao")
    public void kakaoCallback(@RequestParam String code)  {
        System.out.println(code);
        userService.getKaKaoAccessToken(code);
    }

}

보시면 사용자가 저 페이지로 접근하게 되면 아까와 같이 로그인을 진행하고 code를 뱉어냅니다. 해당 코드를 가지고 userService클래스에 getKaKaoAccessToken메서드를 접근합니다.

package com.Service;

import com.Repository.UsersRepository;
import lombok.RequiredArgsConstructor;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

@Service
@RequiredArgsConstructor
public class UserService {

    private final UsersRepository usersRepository;

    public String getKaKaoAccessToken(String code) {
        String accessToken = "";
        String refreshToken = "";
        String reqURL = "https://kauth.kakao.com/oauth/token";

        try {
            HttpURLConnection conn = connectTokenUrl(code, reqURL);
            JSONObject response = getToken(conn);
            System.out.println("AccessToken : " + response.get("access_token"));
            System.out.println("RefreshToken : " + response.get("refresh_token"));

            return response.get("access_token").toString();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private HttpURLConnection connectTokenUrl(String code, String reqURL) throws IOException {
        URL url = new URL(reqURL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setRequestMethod("POST");
        conn.setDoOutput(true);

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
        StringBuilder sb = new StringBuilder();
        sb.append("grant_type=authorization_code");
        sb.append("&client_id={REST_API_KEY}");
        sb.append("&redirect_uri=http://localhost:8080/kakao");
        sb.append("&code=" + code);
        bw.write(sb.toString());
        bw.flush();
        bw.close();

        return conn;
    }

    private JSONObject getToken(HttpURLConnection conn) throws IOException, ParseException {
        int responseCode = conn.getResponseCode();
        System.out.println("responseCode : " + responseCode);

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder result = new StringBuilder();
        String line = "";

        while((line = br.readLine()) != null)
            result.append(line);
        br.close();

        return getJsonData(result.toString());
    }

    private JSONObject getJsonData(String json) throws ParseException {
        JSONParser parser = new JSONParser();
        return (JSONObject) parser.parse(json);
    }

}

제가 코드를 좀 수정했는데요 항목별로 메서드를 추출했습니다.
먼저 getAccessKaKaoToken을 보겠습니다.

다음으로 요청할 API가 "/oauth/token"이기에 따로 String으로 저장했습니다. 먼저 저희가 아까 위에서 POSTMAN으로 날린거처럼 URL에 요청을하려고합니다.

그 메서드가 바로 connectTokenUrl입니다. 그렇게 접속이 끝난후 해당 conn을 리턴해줍니다.
이제 토큰을 얻어보겠습니다. 먼저 ResponseCode를 받게되는데요.

성공하면 200, 실패하면 400이 뜹니다.
200이 뜨면 이제 해당 토큰을 리턴해주게됩니다. JsonData형태로 반환해주었습니다.

이제 처음부터 실행하게되면 콘솔에 AccessToken이 발급된 것을 확인할 수있습니다.

다음 포스팅은 이 토큰을가지고 사용자의 정보를 가져오도록 하겠습니다.




반응형