SpringBoot Security 없이 Oauth2.0 로그인 Kakao편

 

카카오 Developers 방문

https://developers.kakao.com/

 

Kakao Developers

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

developers.kakao.com

 

카카오 Developers에 방문한 뒤 애플리케이션을 추가해 준다.

 

 

카카오 로그인을 활성화 해준다.

 

 

동의 항목 관련 설정을 해준다.

 

 

 

발급 된 키들을 기억 해 둔다.

 

내 애플리케이션 > 제품설정 > 카카오 로그인 > 보안에서 Client Secret키를 발급 받는다.

Client Secret 값은 절대 노출하면 안 된다. (Admin키)

 

인가코드 받기

카카오 로그인은 인가 코드 요청 단계에서 클라이언트에 카카오 계정 정보 또는 카카오톡을 통해 사용자를 인증하는 과정을 거친다. 이후 동의 화면을 출력하고 사용자로 부터 제 3자 정보제공 등의 동의를 받아 인가코드를 발급한다.

 

사용자가 클라이언트에 이미 카카오 계정으로 로그인한 상태라면 다시 계정 정보나 카카오톡으로 로그인을 요청하지 않고 곧바로 동의 화면을 출력한다.  이는 웹 브라우저에 로그인한 카카오 계정 세션이 존재하는지로 판단한다.

 

사용자가 동의하기 버튼을 누르면 카카오 인증서버는 해당 사용자에 대한 인가 코드를 발급해 서비스의 redirect_uri에 전달한다. 

 

 

사이트 도메인과 Redirect URL 등록

 

앱 설정 > 플랫폼에서 사이트 도메인을 등록해 준다.

 

 

밑에 Redirect URL "등록하러 가기" 버튼을 눌러서 Redirect URL을 등록해 준다. 사용자가 카카오 인증을 끝내고 인가 코드를 전달받을 수 있는 URL이다.

 

 

 

여기까지 완료 했으면 카카오톡 로그인 페이지로 이동하기 위해 REST_API_KEY와 REDIRECT_URL를 아래와 같이 담아 GET 요청을 보내야 한다.

 

GET /oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code HTTP/1.1
Host: kauth.kakao.com

 

아래와 같은 과정을 거치면 인가 코드를 얻어 올 수 있다!

 

 

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Kakao Login</title>
</head>
<body>
    <a href="https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}">
        kakao 로그인 페이지로 이동
    </a>
</body>
</html>

 

 

나는 redirect url을 http://localhost:8080/kakao/code로 지정하였다. 위에서 동의하고 계속하기를 누르면 해당 url로 리다이렉트 된다.

 

@RestController()
@RequestMapping("/kakao")
public class KakaoController {

    @GetMapping("/code")
    public String getCode(@RequestParam String code) {
        return "코드 : " + code;
    }
}

 

Access Token 받기

인가 코드를 받은 뒤, 인가 코드로 액세스 토큰과 리프레시 토큰을 발급받는 API를 사용해야 한다. "인가 코드 받기" 만으로는 카카오 로그인이 완료 되지 않는다. 토큰 받기 까지 마쳐야 카카오 로그인을 정상적으로 완료할 수 있다.

 

필수 파라미터들을 담아 POST로 요청한다. 요청 성공시, 응답은 JSON 객체로 Redirect URL에 전달된다. 응답 객체는 액세스토큰과 리프레스 토큰, 초 단위로 된 만료시간을 포함한다.

 

카카오 계정의 세션 인증 시간은 기본 24시간, 최초 인증 후 세션 시간은 변경되지 않는다. 사용자가 로그인 유지를 선택한 경우에는 인증 시간이 1달이다.

 

액세스 토큰은 사용자 정보 가져오기 같은 카카오 로그인이 필요한 API를 호출 할 때 사용된다. 토큰 받기에 성공하여 카카오 로그인을 완료 했다면, 사용자 정보 요청을 통해 필요한 사용자 정보를 받아 서비스 회원 가입 및 로그인을 처리한다.

 

필수 파라미터 담기

curl -v -X POST "https://kauth.kakao.com/oauth/token" \
 -d "grant_type=authorization_code" \
 -d "client_id={REST_API_KEY}" \
 -d "redirect_uri={REDIRECT_URI}" \
 -d "code={AUTHORIZATION_CODE}"

 

 

위에서 얻은 인가 코드를 바탕으로 아래와 같이 파라미터들을 만들어 준다. 인가 코드 이외에 Client ID와 Client Secret 그리고 Redirect URL이 필요하다.

 

  private MultiValueMap<String, String> generateParam(String code) {
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("grant_type","authorization_code");
        params.add("client_id",CLIENT_ID);
        params.add("redirect_uri", REDIRECT_URL);
        params.add("code", code);
        params.add("client_secret", CLIENT_SECRET);
        return params;
    }

 

 

https://kauth.kakao.com/oauth/token에 요청을 보내기 위해 필요한 헤더와 위에서 만든 파라미터로 HTTP Request를 만든다.

 

    @GetMapping("/auth")
    public ResponseEntity<String> auth(@RequestParam String code) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
                new HttpEntity<>(generateParam(code), headers);

        return requestAuth(kakaoTokenRequest);
    }

 

 

RestTemplate를 사용하여 이 reqeust를 보낸다.

 

    private ResponseEntity<String> requestAuth(HttpEntity request) {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.exchange(
                "https://kauth.kakao.com/oauth/token",
                HttpMethod.POST,
                request,
                String.class
        );
    }

 

정상적으로 응답을 받아왔다.

 

 

 

사용자 정보를 얻어 올 때 토큰 정보를 사용해야 하니 데이터 클래스를 하나 만들어 매핑해 두자. 자세한 내용은 github 참조.

 

 

사용자 정보 가져오기

위에서 얻은 액세스 토큰을 활용하여 사용자 정보를 가져와 보자.

 

 

얻은 액세스 토큰에 Bearer를 붙혀 Authorization 헤더에 넣어 요청을 보내면 응답이 온다.

 

  private HttpEntity<MultiValueMap<String, String>> generateProfileRequest(OauthToken oauthToken) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer "+ oauthToken.getAccess_token());
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
        return new HttpEntity<>(headers);
    }

 

 private ResponseEntity<String> requestProfile(HttpEntity request) {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.exchange(
                "https://kapi.kakao.com/v2/user/me",
                HttpMethod.POST,
                request,
                String.class
        );
    }

 

정상적으로 emiail 응답을 받았다!  카카오로 로그인 시 이 정보를 사용하여 사용자를 생성 혹은 조회 하면 될 듯 하다!

 

 

 

https://github.com/DWL5/springboot-oauth/tree/auth_login_kakao

 

DWL5/springboot-oauth

Contribute to DWL5/springboot-oauth development by creating an account on GitHub.

github.com

 

댓글



Designed by JB FACTORY