본문 바로가기
OAuth/Kakao Login API

[Kakao Login API] 카카오 계정의 유저 정보 받아오기 및 마무리 (Spring Boot 환경에서 카카오 로그인 API RESTful방식으로 연동하기 -4장 마무리) (0)

by 임채훈 2019. 3. 23.


2019/03/22 - [OAuth/Kakao Login API] - [Kakao Login API] 카카오 로그인 API 서비스 구현 (Spring Boot 환경에서 카카오 로그인 API RESTful방식으로 연동하기 -3장)

2019/03/22 - [OAuth/Kakao Login API] - [Kakao Login API] 프로젝트 생성 및 기본 구성 셋팅 (Spring Boot 환경에서 카카오 로그인 API RESTful방식으로 연동하기 -2장)

2019/03/22 - [OAuth/Kakao Login API] - [Kakao Login API] 카카오 로그인 API 사용 준비하기 (Spring Boot 환경에서 카카오 로그인 API RESTful방식으로 연동하기 -1장)



이번엔 이전장에서의 작업을 통해 받아온 유저 토큰(AccessToken)을 이용해 해당 유저의 카카오 계정에 대한 여러가지의 정보를 가져오고 로그아웃 기능을 끝으로 마무리하도록 하곘습니다.



1. 일단 정보요청에 관한 개발가이드를 읽어봅시다.





- 요청(Request)방식 입니다.  https://kapi.kakao.com/v2/user/me의 경로로 헤더에 Authorization란 key로 "Bearer {access_Token}"을 담아서 보내라고 나와있습니다.





2. 요청에 대한 Response와 관련된 내용입니다.



- 저는 아래의 사진중 첫번째 방식인 전체 정보를 얻어와서 원하는 정보를 꺼내는 형식으로 구현하곘습니다.





3. 실제로 요청이 성공적으로 수행됐을때의 Response JSON객체 형태입니다.





4. 그럼 이제 위의 내용을 참고해서 코드로 기능을 구현해보도록 하겠습니다.


1. 유저의 정보는 이메일로 회원가입 하지 않은 회원이 존재할 수 있고, 클라이언트마다 정보 제공의 동의여부가 다를 수 있기때문에 HashMap타입을 통해 정보를 받도록 합니다.

2. 컨트롤러 login메소드에서 getUserInfo 메소드를 통해 받아온 유저정보에 email정보가 있을때 세션에 토큰과 이메일을 등록합니다. (지금은 간단하게 로그인API를 사용해보고자 하는것임으로 간단하게 session에 등록하겠습니다.)

3. 로그인이 성공적으로 이루어졌을때 로그아웃이 가능하도록 하기위해 이전에 작성했던 index.jsp파일에서 로그인 성공했을때 나타내는 부분에 로그아웃 버튼을 추가해줍니다.


- com.personal.kakaoLogin.service.KakaoAPI.java 파일에 getUserInfo 메소드 추가


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public HashMap<String, Object> getUserInfo (String access_Token) {
    
    //    요청하는 클라이언트마다 가진 정보가 다를 수 있기에 HashMap타입으로 선언
    HashMap<String, Object> userInfo = new HashMap<>();
    String reqURL = "https://kapi.kakao.com/v2/user/me";
    try {
        URL url = new URL(reqURL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        
        //    요청에 필요한 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("nickname", nickname);
        userInfo.put("email", email);
        
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    return userInfo;
}
cs



- com.personal.kakaoLogin.controller.HomeController.java 파일수정


1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping(value="/login")
public String login(@RequestParam("code"String code, HttpSession session) {
    String access_Token = kakao.getAccessToken(code);
    HashMap<String, Object> userInfo = kakao.getUserInfo(access_Token);
    System.out.println("login Controller : " + userInfo);
    
    //    클라이언트의 이메일이 존재할 때 세션에 해당 이메일과 토큰 등록
    if (userInfo.get("email"!= null) {
        session.setAttribute("userId", userInfo.get("email"));
        session.setAttribute("access_Token", access_Token);
    }
    return "index";
}
cs



- src/main/webapp/WEB-INF/views/index.jsp 파일수정


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>
    <c:if test="${userId eq null}">
        <a href="https://kauth.kakao.com/oauth/authorize
            ?client_id=b5f85af25d1bdf961d4f2016bafe3c6e
            &redirect_uri=http://localhost:8000/login
            &response_type=code">
            <img src="/img/kakao_account_login_btn_medium_wide_ov.png">
        </a>
    </c:if>
    <c:if test="${userId ne null}">
        <h1>로그인 성공입니다</h1>
        <input type="button" value="로그아웃" onclick="location.href='/logout'">
    </c:if>
</body>
cs




5. 결과 화면입니다. 유저 정보가 성공적으로 넘어오는것을 확인할 수 있습니다.




6. 로그아웃 기능 구현하기


로그아웃 기능은 간단합니다.

개발가이드를 참고하면 https://kapi.kakao.com/v1/user/logout 경로를 통해 헤더에 Authorization : "Bearer {access_Token}" 을 포함하여 요청하면 로그아웃을 수행한 클라이언트의 아이디를 반환한다고 합니다.


- com.personal.kakaoLogin.service.KakaoAPI.java 파일에 kakaoLogout 메소드 추가


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void kakaoLogout(String access_Token) {
    String reqURL = "https://kapi.kakao.com/v1/user/logout";
    try {
        URL url = new URL(reqURL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization""Bearer " + access_Token);
        
        int responseCode = conn.getResponseCode();
        System.out.println("responseCode : " + responseCode);
        
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        
        String result = "";
        String line = "";
        
        while ((line = br.readLine()) != null) {
            result += line;
        }
        System.out.println(result);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
cs



- com.personal.kakaoLogin.controller.HomeController.java 파일에 Logout요청을 받을 Logout메소드 작성


로그인 할 때 세션에 넣어두었던 토큰을 꺼내서 로그아웃 메소드를 실행합니다.


1
2
3
4
5
6
7
@RequestMapping(value="/logout")
public String logout(HttpSession session) {
    kakao.kakaoLogout((String)session.getAttribute("access_Token"));
    session.removeAttribute("access_Token");
    session.removeAttribute("userId");
    return "index";
}
cs




로그아웃 기능을 끝으로 카카오 로그인 API를 직접 사용해보았습니다.


직접 구현해본 기능 외에 Refresh Token을 이용한 Access Token 갱신, 사용자 리스트 요청, 앱 연결 해제 등도 결국 비슷비슷한 방식으로 구현하면 됩니다.


많은 도움이 되셨길 바라며 잘못된 부분이나 수정이 필요한 부분이 있다면 알려주시면 감사하겠습니다 ㅜㅜ

댓글