본문 바로가기
Language/Spring

[SPRING] 카카오 로그인 스프링 Rest API 예제 및 쉬운 구현 방법 - OAuth 2.0, Javascript, Jsp

by tyrannojung 2021. 7. 15.
반응형

 웹뷰를 앱으로 만드는 과정에 있어서, 카카오 로그인의 동작이 안돼 기존 자바스크립트 방식을 'REST API' 방식으로 바꾸게 되었습니다.

 

카카오 로그인 API 사용을 위한 애플리케이션 설정

 

카카오 디벨로퍼 페이지에서 애플리케이션을 만들어 주고 활성화까지만 진행하면됩니다. 

활성화까지 어려움이 있으신분들은 아래 링크에서 ‘애플리케이션 설정부분’을 참조해주세요.

https://tyrannocoding.tistory.com/49

 

[자바스크립트] 카카오 로그인 API 쉽게 구현 방법 및 예제- OAuth 2.0, Javascript, Jsp

 카카오 로그인 API (OAuth 2.0)  클라이언트 입장에서 수많은 사이트의 모든 아이디 비밀번호를 기억하기는 쉽지 않습니다. 또한 서비스를 제공해주는 리소스 오너 또한 안전하게 보관하여야 하

tyrannocoding.tistory.com

 

코드 - 서버 구현 (SPRING - LEGACY)

 

자바스크립트를 통해 구현할 때와 동일하게 애플리케이션을 만들고 활성화해주면 앱 키를 사용하실 수 있습니다. 우리는 'REST API키'를 사용합니다.

 

 

pom.xml

 

<dependency>
	<groupId>com.googlecode.json-simple</groupId>
	<artifactId>json-simple</artifactId>
	<version>1.1.1</version>
</dependency>

<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.8.7</version>
</dependency>

 

java

 

@Controller
public class KakaoController {

@RequestMapping(value = "/login/getKakaoAuthUrl")
	public @ResponseBody String getKakaoAuthUrl(
			HttpServletRequest request) throws Exception {
		String reqUrl = 
				"https://kauth.kakao.com/oauth/authorize"
				+ "?client_id=f8071907fae4877f2a0f469e969f639f"
				+ "&redirect_uri=http://localhost:8181/login/oauth_kakao"
				+ "&response_type=code";
		
		return reqUrl;
	}
	
	// 카카오 연동정보 조회
	@RequestMapping(value = "/login/oauth_kakao")
	public String oauthKakao(
			@RequestParam(value = "code", required = false) String code
			, Model model) throws Exception {

		System.out.println("#########" + code);
        String access_Token = getAccessToken(code);
        System.out.println("###access_Token#### : " + access_Token);
        
        
        HashMap<String, Object> userInfo = getUserInfo(access_Token);
        System.out.println("###access_Token#### : " + access_Token);
        System.out.println("###userInfo#### : " + userInfo.get("email"));
        System.out.println("###nickname#### : " + userInfo.get("nickname"));
       
        JSONObject kakaoInfo =  new JSONObject(userInfo);
        model.addAttribute("kakaoInfo", kakaoInfo);
        
        return "/home"; //본인 원하는 경로 설정
	}
	
    //토큰발급
	public String getAccessToken (String authorize_code) {
        String access_Token = "";
        String refresh_Token = "";
        String reqURL = "https://kauth.kakao.com/oauth/token";

        try {
            URL url = new URL(reqURL);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            //  URL연결은 입출력에 사용 될 수 있고, POST 혹은 PUT 요청을 하려면 setDoOutput을 true로 설정해야함.
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);

            //	POST 요청에 필요로 요구하는 파라미터 스트림을 통해 전송
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
            StringBuilder sb = new StringBuilder();
            sb.append("grant_type=authorization_code");
            sb.append("&client_id=f8071907fae4877f2a0f469e969f639f");  //본인이 발급받은 key
            sb.append("&redirect_uri=http://localhost:8181/login/oauth_kakao");     // 본인이 설정해 놓은 경로
            sb.append("&code=" + authorize_code);
            bw.write(sb.toString());
            bw.flush();

            //    결과 코드가 200이라면 성공
            int responseCode = conn.getResponseCode();
            System.out.println("responseCode : " + responseCode);

            //    요청을 통해 얻은 JSON타입의 Response 메세지 읽어오기
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = "";
            String result = "";

            while ((line = br.readLine()) != null) {
                result += line;
            }
            System.out.println("response body : " + result);

            //    Gson 라이브러리에 포함된 클래스로 JSON파싱 객체 생성
            JsonParser parser = new JsonParser();
            JsonElement element = parser.parse(result);

            access_Token = element.getAsJsonObject().get("access_token").getAsString();
            refresh_Token = element.getAsJsonObject().get("refresh_token").getAsString();

            System.out.println("access_token : " + access_Token);
            System.out.println("refresh_token : " + refresh_Token);

            br.close();
            bw.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return access_Token;
    }
	
    //유저정보조회
    public HashMap<String, Object> getUserInfo (String access_Token) {

        //    요청하는 클라이언트마다 가진 정보가 다를 수 있기에 HashMap타입으로 선언
        HashMap<String, Object> userInfo = new HashMap<String, Object>();
        String reqURL = "https://kapi.kakao.com/v2/user/me";
        try {
            URL url = new URL(reqURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");

            //    요청에 필요한 Header에 포함될 내용
            conn.setRequestProperty("Authorization", "Bearer " + access_Token);

            int responseCode = conn.getResponseCode();
            System.out.println("responseCode : " + responseCode);

            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            String line = "";
            String result = "";

            while ((line = br.readLine()) != null) {
                result += line;
            }
            System.out.println("response body : " + result);

            JsonParser parser = new JsonParser();
            JsonElement element = parser.parse(result);

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

            String nickname = properties.getAsJsonObject().get("nickname").getAsString();
            String email = kakao_account.getAsJsonObject().get("email").getAsString();
            
            userInfo.put("accessToken", access_Token);
            userInfo.put("nickname", nickname);
            userInfo.put("email", email);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return userInfo;
    }
 }

 

javascript & jsp

 

<html>

<head>
	<title>Home</title>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
	<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
  <body>
  <ul>
      <li onclick="kakaoLogin();">
        <a href="javascript:void(0)">
            <span>카카오 로그인</span>
        </a>
      </li>
  </ul>

  <script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
  <script>
  //카카오로그인
  function kakaoLogin() {

    $.ajax({
        url: '/login/getKakaoAuthUrl',
        type: 'get',
        async: false,
        dataType: 'text',
        success: function (res) {
            location.href = res;
        }
    });

  }

  $(document).ready(function() {

      var kakaoInfo = '${kakaoInfo}';

      if(kakaoInfo != ""){
          var data = JSON.parse(kakaoInfo);

          alert("카카오로그인 성공 \n accessToken : " + data['accessToken']);
          alert(
          "user : \n" + "email : "
          + data['email']  
          + "\n nickname : " 
          + data['nickname']);
      }
  });  

  </script>
  </body>
</html>

 

요약

 

 해당 코드를 전체 복사하고 붙여넣되, client_id는 앱 키의 REST_API 키를,  redirect_uri는 내가 애플리케이션 설정에서 등록한 Redirect_uri를 등록해야 합니다. 
 getKakaoAuthUrl(HttpServletRequest request)를 통해 카카오 로그인 페이지로 이동합니다. 그리고 로그인이 성공하면 카카오는 토큰을 발급해주며, 해당 토큰을 통해 유저 정보를 가져올 수 있습니다.

 

 

정리

 카카오 로그인은 자바스크립트로만 사용해도 정말 쉽게 훌륭한 기능을 만들 수 있지만, 저같은 경우는 Webview를 활용해 어플을 개발해야만 했습니다. 그런데 카카오 로그인을 사용하려면 native코딩을 해야 하는데, 그럴 경우 제가 구현한 개발환경인 expo를 eject 해야만 했습니다. 

 expo를 사용하는 이유는 정말 누구나 쉽게 어플리케이션을 만드는 것이므로 eject 하고 싶지 않았고, 그래서 약간 우회적인 방법으로 rest api로 카카오 로그인을 구현했습니다. 

 

 여러가지를 참고하여 만든 것으로 혹시라도 잘못됐거나 안 되는 점 있으면 댓글 남겨주시면 감사하겠습니다!

 

반응형

댓글