본문 바로가기
Spring

[Spring] REST 방식으로 카카오 로그인 구현하기 - 1

by 태진아밴드 2020. 10. 5.

개발 초기에는 sns로그인을 javascript sdk를 이용하여 구현했었다.

 

그러나 보안상의 이슈도 있고 아이폰일경우에 기존 로그인창으로 되돌아오지 않는 현상이 발생하여

 

그냥 REST 방식으로 변경하기로 결정..!

 

네이버로그인과 카카오 로그인 둘 다 구현했어서 일단 카카오로 구현했던 과정을 먼저 포스팅하려고한다.

 

먼저 카카오개발자로 들어가서 카카오 로그인용 REST API용 키를 발급받자.

 

https://developers.kakao.com/

 

Kakao Developers

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

developers.kakao.com

키를 발급받은 이후에 제품설정으로 들어가서 카카오 로그인의 Redirect URI를 설정해준다.

 

http://localhost:2080/login/oauth_kakao

 

로컬에서 먼저 테스트하기위해 로컬테스트용으로 주소를 추가했다.

 

이제 준비단계에서 카카오 로그인창을 호출해보자.

 

API호출에 관련된부분은 카카오개발자내의 REST API 문서에 잘 정리되어있다.

 

 

* URL

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

* Parameter

Name Type Description Required
client_id String 앱 생성 시 발급 받은 REST API 키 O
redirect_uri String 인증 코드가 리다이렉트될 URI O
response_type String "code"로 고정 O
state String 로그인 이전 상태를 유지하기 위해 저장하는 값
결과가 리다이렉트될 때 입력한 state 값이 그대로 전달됨
URL Encoded 문자열이어야 함
Cross-site Request Forgery 공격 보호를 위해 활용 가능
X
auth_type String 보안을 위해 사용자가 이미 로그인한 상태에서 다시 한 번 사용자 인증이 필요할 때 값을 "reauthenticate"로 지정하여 사용
이 파라미터가 요청에 포함되었고 값이 "reauthenticate"라면 카카오 인증 서버는 기존 사용자 인증 여부와 상관없이 사용자에게 카카오계정 로그인 화면을 출력함
카카오톡 인앱 브라우저에서는 이 기능이 제공되지 않음
X

* Response

Key

Name Type Description
code String 사용자 토큰 받기 요청에 필요한 인증 코드

Error Message

Error Error_desc Description
access_denied User denied access 사용자가 동의 화면에서 '동의하고 계속하기'를 누르지 않고
로그인을 취소한 경우
access_denied Not allowed under age 14 만14세 미만 사용자의 보호자 동의 실패

 

위와같이 최초 로그인창 호출시에 발급받은 키와 아까 설정한 Redirect URI를 넣어서 호출해주면된다.

 

우선 컨트롤러단 코드부터 보자.

* java

// 카카오 로그인창 호출
@RequestMapping(value = "/login/getKakaoAuthUrl")
public @ResponseBody String getKakaoAuthUrl(HttpServletRequest request) throws Exception {
	String reqUrl = kakaoAuthUrl + "/oauth/authorize?client_id=" + kakaoApiKey + "&redirect_uri="+ redirectURI + "&response_type=code";
	return reqUrl;
}

 

properties에 별도로 변수로 잡아둔 kakaoAuthUrl, kakaoApiKey, redirectURI 를 넣어서 url을 리턴해주는 형태이다.

 

이제 스크립트 단에서 해당부분을 호출해주자.

* javascript

// 카카오 로그인 버튼 클릭
function loginWithKakao() {
    $.ajax({
        url: '/login/getKakaoAuthUrl',
        type: 'get',
    }).done(function (res) {
        location.href = res;
    });

}

 

ajax로 해당 컨트롤러를 호출한뒤 리턴받은 url을 띄우면 카카오 로그인창이 뜨게된다.

 

이제 로그인 이후 과정부분을 보자. 카카오 개발자에서 설정했던 Redirect URI에 해당하는 부분이다.

 

// 카카오 연동정보 조회
@RequestMapping(value = "/login/oauth_kakao")
public String oauthKakao(HttpServletRequest request, HttpServletResponse response) throws Exception {
	
    String code = request.getParameter("code");
    String error = request.getParameter("error");
    // 카카오로그인 페이지에서 취소버튼 눌렀을경우
    if (error != null) {
        if (error.equals("access_denied")) {
            return "redirect:/login";
        }
    }

    String accessToken = getAccessToken(code);
    String kakaoUniqueNo = getKakaoUniqueNo(accessToken);

    if (kakaoUniqueNo != null && !kakaoUniqueNo.equals("")) {
        /** 
        
            TO DO : 리턴받은 kakaoUniqueNo에 해당하는 회원정보 조회 후 로그인 처리 후 메인으로 이동
        
        */

    return "redirect:/";
    
    // 카카오톡 정보조회 실패했을경우
    } else {
        throw new ErrorMessage("카카오톡 정보조회에 실패했습니다.");
    }

}

 

일단 getAccessToken를 통해 토큰값을 얻은 뒤 getKakaoUniqueNo를 통해 사용자 고유번호를 추출한다.

 

추출한 kakaoUniqueNo로 회원 테이블에서 해당하는 정보가 있는지 조회.

 

일치하는 정보가 있다면 해당회원으로 로그인 시키고, 없다면 해당 회원이 없음을 알리고 회원가입으로 이동시키는 식으로 구현했다.

 

( 로그인 관련 상세코드는 TO DO 로 주석처리 하였다.🤫 )

 

getAccessToken, getKakaoUniqueNo 둘 다 API를 호출 하게되는데 이건 다음에 이어서 쓰도록 하겠다.