💐 Spring/Spring Security

[Spring Security] 스프링 부트 OAuth2를 이용한 카카오 계정 로그인 (직접 구현)

iseunghan 2021. 4. 29. 18:12
반응형

이번 시간에는 카카오 계정으로 로그인하는 방법에 대해서 알아보겠습니다. :D

참고 :

  • 구글 계정으로 로그인은 여기를 참조하시기 바랍니다.
  • 네이버 계정으로 로그인은 여기를 참조하시기 바랍니다.
  • 소셜 로그인을 하기위해 필요한 API 키 발급은 여기를 참조하시기 바랍니다.

 

카카오 로그인 버튼 구현하기

일단 카카오에서 제공하는 로그인 버튼을 받아서 사용하겠습니다.

카카오에서 제공하는 버튼 이미지

 

이미지를 다운 받았으면, 이제 버튼에 링크를 달면 됩니다.

 

Request 요청 링크

{REST_API_KEY} 부분에는 앱 생성 시 발급받은 REST API 키를 넣어주면 되고, 나머지도 아래 표를 보고 알맞게 넣어주면 된다.

URL을 아까 받은 이미지와 함께 넣어줍니다. (발급 받으신 client_id랑 uri는 직접 넣으셔야합니다.)

<a href="https://kauth.kakao.com/oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code"><img src="/image/kakao_login_medium.png"></a>

그리고 실행해보면,

이렇게 카카오 정보 동의 화면이 뜨게 되는데, 이건 이미 로그인을 한 상태라 그렇습니다.

로그아웃을 해보고 실행해보면 어떻게 될까요?

이렇게 로그인을 하는 페이지가 나오게 됩니다.

로그인을 하고 [동의하고 계속하기] 를 클릭한다면? 

우리가 설정한 Redirect URI로 응답이 오게 되는데, 뒤에 code를 가지고 응답이 오게 됩니다. 이 코드가 있으면 정상적으로 인증이 됐다는 뜻입니다. (404 에러가 뜨는 이유는 해당 url 컨트롤러를 만들지 않았기 때문입니다.)

 

컨트롤러 작성

MemberOauth2Controller라고 클래스를 만들었습니다.

@RestController
@RequestMapping(value = "/login/oauth2/code")
public class MemberOauth2Controller {

    @GetMapping(value = "/kakao")
    public String kakaoOauthRedirect(@RequestParam String code) {
        return "카카오 로그인 인증 완료, code : " + code;
    }
}

@RequestParam은 파라미터의 타입이 기본 타입이거나 쿼리 스트링의 기본 타입인 String인 경우 어노테이션 생략 가능합니다.

 

Response :

http://localhost:8080/login/oauth2/code/kakao?code={AUTHORIZE_CODE}

성공적으로 인가 코드를 받았습니다.

 

엑세스 토큰 발급 받기

이전에 받았던 인가 코드를 이용해서 계정 정보에 접근할 수 있는 Access Token을 받아 보도록 하겠습니다.

 

위의 문서처럼 요청을 보내면 됩니다.

 

Request:

// 카카오에 POST방식으로 key=value 데이터를 요청함. RestTemplate를 사용하면 요청을 편하게 할 수 있다.
RestTemplate rt = new RestTemplate();

// HttpHeader 오브젝트 생성
HttpHeaders headers = new HttpHeaders();
headers.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", "{client_id}");
	params.add("redirect_uri", "http://localhost:8080/login/oauth2/code/kakao");
	params.add("code", code);
	params.add("client_secret", "{secret_code}");

// HttpHeader와 HttpBody를 HttpEntity에 담기 (why? rt.exchange에서 HttpEntity객체를 받게 되어있다.)
HttpEntity<MultiValueMap<String, String>> kakaoRequest = new HttpEntity<>(params, headers);

// HTTP 요청 - POST방식 - response 응답 받기
ResponseEntity<String> response = rt.exchange(
    "https://kauth.kakao.com/oauth/token",
    HttpMethod.POST,
    kakaoRequest,
    String.class
);

요청을 쉽게 보낼 수 있는 라이브러리가 있는데, 그 중 하나가 RestTemplate 입니다.

HttpHeaders를 생성해서 헤더에 값을 넣어주고, MultiValueMap을 이용해서 key:value 데이터 형식으로 값을 넣어줍니다.

그리고, HttpEntity에 바디 부분에 해당되는 MultiValueMap을 넣어줍니다. (요청을 보낼 때, HttpEntity를 넣어야 하기 때문에 한번 더 감싼 형태입니다.)  이제 kakaoRequest는 바디, 헤더를 둘 다 가지고 있는 인스턴스가 됩니다.

 

Response:

위 예시처럼 응답이 왔으면, 이제 계정 정보에 접근하기 위해 필요한 access_token을 받았습니다!

 

사용자 정보 가져오기

요청은 위와 같이 하시면 됩니다.

 

Request:

// 여기서부터, Access Token을 이용해서 사용자 정보를 응답 받는 코드이다.
HttpHeaders headers1 = new HttpHeaders();
headers1.add("Authorization", "Bearer " + kakaoOauthParams.getAccess_token());
headers1.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

HttpEntity<HttpHeaders> kakaoRequest1 = new HttpEntity<>(headers1);

ResponseEntity<String> profileResponse = rt.exchange(
	"https://kapi.kakao.com/v2/user/me",
	HttpMethod.POST,
	kakaoRequest1,
	String.class
);

kakaoOauthParams.getAccess_token() 이 부분은 위에서 받은 응답을 ObjectMaper를 이용해서 객체에 담아서 값을 사용했습니다.

 

성공하시면, 아래와 같이 응답을 받을 수 있습니다.

감사합니다~


REFERENCE

 

Kakao Developers

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

developers.kakao.com

반응형