django 카카오 소셜 로그인 api

solee·2022년 3월 20일
2

Django

목록 보기
12/12

로그인에 관한 카카오 공식 문서에 가면 이런 이미지가 있다.

개념 자체는 어렵지 않다.

  1. 카카오 로그인 요청을 보낸다.
  2. 카카오 서버에서 인가 코드를 돌려받는다.
  3. 코드를 카카오 서버에 보낸다.
  4. 카카오 서버에서 카카오 액세스 토큰을 돌려받는다.
  5. 액세스 토큰을 보내고 사용자 정보를 가져온다.
  6. 카카오 서버에서 돌려받은 사용자 정보로 우리 서버에 가입시킨다.

어디로 어떤 요청을 보내야 하는지에 대해서도 공식 문서를 살펴보면 된다. 단계별로 살펴보자!




REST api

REST api를 사용하므로 해당 문서로 이동하면, 먼저 애플리케이션을 등록해야 한다. 몇 가지 사전 설정이 있는데, 어렵지 않으니 애플리케이션을 등록하고 카카오 로그인을 ON으로 바꿔 활성화하고, Redirec URI를 등록하고 마지막으로 동의 항목을 설정하는 과정은 스킵한다.

이메일을 받기 위해서는 카카오 비즈앱 전환 설정이 필요한데, 이 또한 데브톡에서 신청하니 엄청나게 빠른 답변과 함께 전환해 주셨다! id가 오기는 하지만 지금 작업중인 프로젝트가 이력서를 관리하고 채용 공고에 지원하는 사이트를 클론하는 거라 이력서에 입력하기 위해 이메일이 필요했다.

카카오 로그인과 api 사용에 대해서는 부끄럽지만 아주 기초적으로, 간단하게, 일단 코드가 돌아가는 걸 목표로 간단하게만 적어두겠다.




인가 코드 요청하기

인가 코드 받기 탭에 가면 이런 것이 있다.

아래로도 길지만 필수적인 파라미터만 보면 이렇다. 그러면 자세히 살펴보자!

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

GET 요청을 보내야 한다. 어디로 보내냐면 kaoth.kakao.com에 /oauth/authorize?로 필수 파라미터를 줄줄 달아서 보내야 한다!

더 간단하게 생각하자면,

http://kauth.kakao.com/oauth/authorize?client_id={키}&redirect_uri={콜백URI}&response_type=code

여기로 요청을 보내야 한다.
위의 안내 이미지에서 보는 것처럼, 내 앱의 api 키와 인가 코드를 돌려받을 콜백 uri, 그리고 response_type=code이다. 이 링크에 제대로 된 값을 넣어서 주소창에 넣어 봐도 작동하지는 않는데, 대신 이렇게 하자.

리다이렉트 모듈을 사용해 요청을 보낸다.
클라이언드 id가 나의 앱 키로 사실 이것도 보안 적용해 보관해야 하는 것인데, 나는 이 부분은 어차피 프론트에서 요청을 받을 예정이었으므로 그냥 두었다.
callback uri란 말 그대로 인가코드가 리다이렉트될 uri라는 뜻인데, 인가 코드를 받을 view와 url을 작성해 보면 알게 된다.

이게 내 users 앱의 urls.py인데, /kakao/callback이라는 요청이 들어오면 callbackView로 연결된다. 그러니까, 카카오 로그인 요청에 대한 코드를 callbackView에서 받으면 된다는 뜻이다.


공식 문서의 response를 보면 이렇다. 인가 코드인 code를 가지고 돌아온다. 나의 리다이렉트 uri로 돌아온다. 그럼 요청이 들어온 것을 어떻게 알 수 있을까?
서버를 보자!!

쿼리 파라미터를 통해 ?code=gkdjfslkfsjlfdjfslkdfjdslkfj 라는 데이터를 담은 요청이 들어온 것을 확인할 수 있다.

그러면 이 code를 받아서 처리하면 되겠지.



  1. 카카오 로그인 요청을 보낸다.
  2. 카카오 서버에서 인가 코드를 돌려받는다.

아까 작성한 flow를 보자면, 로그인 요청은 http://kauth.kakao.com/oauth/authorize?client_id={키}&redirect_uri={콜백URI}&response_type=code 로 요청을 보내서 해결했다. 그리고 인가 코드까지 돌려받은 것이다. 다음은 액세스 토큰이다.



카카오 액세스 토큰 요청하기

다시 공식 문서다.

아까와 비슷하다! kauth.kakao.com의 /oauth/token으로 POST 요청을 보낸다. 아래로 필수 파라미터 4개를 붙여서 보내면 되겠지. 여기서 중요한 것은 바로 code다. 그럼 이 code는 어디에 있을까? 아까 서버에서 확인한, 내가 작성해 준 리다이렉트 uri에 있다! 그러면 받는 view를 작성하면 된다.

code를 담은 요청이 돌아오는 callbackView다. request.GET으로 code를 받아 다른 필수 데이터와 함께 requests 모듈을 사용해 요청을 보낸다.
바로 공식 문서의 response를 보자.

access_token이라는 값이 돌아온다고 한다! 그럼 다시 코드를 보자.

kauth.kakao.com의 /oauth/token, 즉 kauth.kakao.com/oauth/token으로 요청을 보낸다. 이 requests 모듈의 결과물인 response는 출력해 보면 다음과 같고:


타입을 출력해 보면 다음과 같다:

확인할 수 있듯이, 200이라는 건 리턴되는 status 의미한다. 카카오가 우리에게 200을 돌려주는 것이다. 이 결과물에 .json()을 해 줌으로써 결과물을 json, 즉 우리에게는 dict 형식으로 받을 수 있다. 공식 문서에서 보여주는 response란 이 .json()의 결과물이라고 할 수 있다.

여기서 우리에게 필요한 건 access_token이다.

그러므로 .json()한 결과에서 access_token만 꺼낸다.

  1. 코드를 카카오 서버에 보낸다.
  2. 카카오 서버에서 카카오 액세스 토큰을 돌려받는다.

그러면 여기까지 마무리된 것이다.




사용자 정보 요청하기

이번에는 남은 flow를 먼저 보자. 아까 한 것들과 크게 다르지 않다.

  1. 카카오 액세스 토큰을 보내고 사용자 정보를 가져온다.
  2. 카카오 서버에서 돌려받은 사용자 정보로 우리 서버에 가입시킨다.

아까 돌려받은 access_token을 사용해 카카오 서버에서 사용자 정보를 돌려받아야 한다. return이라 자꾸 돌려받는다는 표현을 쓰는데, 정확히는 카카오 사용자 정보 api에 요청을 보내는 것이다.

공식 문서에서 Request를 확인하면 다음과 같다.

이제는 익숙하다! GET 또는 POST 요청을 kapi.kakao.com/v2/user/me로 보낸다. 이번에는 파라미터가 아니라 헤더에 Authorization을 받아서 보내야 한다.

굳이 변수에 새로 할당하는 것을 싫어하는 편이라 이렇게 쓰는데, 다른 사람들의 코드를 보면 조금 더 보기 편하게 저장되어 있다. 그렇게 바꿔 볼까.

여기서 중요한 건 Bearer와 $인데, 다른 팀에서는 $를 붙이지 않아도 되었다고 한다. 나는 없으니 에러가 났었는데, 차이는 잘 모르겠다.

아무튼 get요청을 보내고 그 결과에 .json()을 해서 user_information에 저장한 것이다. 이 데이터를 가지고 서버에 가입시키면 된다!


이 user_information이라는 것은, 공식 문서에도 나와있지만

HTTP/1.1 200 OK
{
    "id":123456789,
    "kakao_account": { 
        "profile_needs_agreement": false,
        "profile": {
            "nickname": "홍길동",
            "thumbnail_image_url": "http://yyy.kakao.com/.../img_110x110.jpg",
            "profile_image_url": "http://yyy.kakao.com/dn/.../img_640x640.jpg",
            "is_default_image":false
        },
        "name_needs_agreement":false, 
        "name":"홍길동",
        "email_needs_agreement":false, 
        "is_email_valid": true,   
        "is_email_verified": true,
        "email": "sample@sample.com",
        "age_range_needs_agreement":false,
        "age_range":"20~29",
        "birthday_needs_agreement":false,
        "birthday":"1130",
        "gender_needs_agreement":false,
        "gender":"female"
    },  
    "properties":{
        "nickname":"홍길동카톡",
        "thumbnail_image":"http://xxx.kakao.co.kr/.../aaa.jpg",
        "profile_image":"http://xxx.kakao.co.kr/.../bbb.jpg",
        "custom_field1":"23",
        "custom_field2":"여"
        ...
    }
}

이런 형태를 한다. 동의 항목에 따라 다르다. 여기서 익숙한 방식대로 데이터를 꺼내 저장하면 되는 것이다.

뭐... 이렇게. id란 long 타입이라고는 하는데 8~10자리 정도의 짧은 수가 오기 때문에 Integer 타입이면 충분할 듯하다.(long타입으로 설정해 주긴 했다! django model에서는 long이 아니라 bigInt를 사용한다.)




마치며

처음에는 카카오 문서를 보면서도 뭘 해야 할지 잘 몰랐는데, 이것저것 찾아보고 뜯어보고 print해보다 보니 감이 왔다. 다시 살필수록 카카오가 얼마나 상냥하게 써 줬는지, 사실 맨 처음에 사용한 이미지는 블로깅하려고 다시 들어가 보았을 때 바뀐, 더 자세한 이미지다. 솔직히 죄송할 만큼 감사하다. 동시에 나도 나중에 이렇게까지 설명해줄 api를 개발해 보고 싶다.
쑥쑥 자라야지!

profile
DA DA DA

1개의 댓글

comment-user-thumbnail
2023년 2월 8일

불필요한 정보 없이 깔끔한 게시글이네요 감사합니다.

답글 달기