[django] Kakao Login API

12249 ワード

本プロジェクトでは、SNS登録を実施することを決定し、KACA登録APIを作成した経験を残した.

1.Kakaoログインシーケンス


https://developers.kakao.com/
「ドキュメント」タブの「kakaログイン」エントリから、「kakaログイン」を実現する方法について説明します.ドラムの場合、REST APIを選択できます.

ソース:https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#before-you-begin
上記の表のように、登録ステップは大きく3つのステップに分けられます.実際、KaKaoAuth Serverとの通信はstpe 2トークンを取得する前に完了し、ステップ3はトークンによってユーザ情報を格納または加工するので、それぞれの状況に応じて使用することができる.
サービスサーバの立場に立ち、サービスClientからKakaoAuthサーバにログイン要求を出し、302 Redirect URIで認証コードを受信した部分から実施します.

2.プリセット


Kakaoに登録するためには,プラットフォーム登録,Kakao登録のアクティブ化,Redirect URI登録,同意項目の決定などのプリセットが必要である.
https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#request-token-info
上記のアドレスを参照してプリセットを行うことができます.ここで、Redirect URIは、上記のシーケンスで対応する承認コードのURIを6回受信したものと考えられる.ローカル開発中の場合は、http://localhost:8000に設定できます.
長期的に見ると、承認コード'Redirect_URI?code='auth_code'Redirect URIアドレスをquery parameterとして使用するため、認証コードを受信し、トークンのViewを要求するアドレスとして設定すると、認証コードを直接受信して使用することができる.

3.コード作成

import json, re, bcrypt, jwt, requests

from django.shortcuts import render, redirect
from django.views     import View
from django.http      import JsonResponse
from django.conf      import settings

from users.models     import User


class KakaoAPI:
    def __init__(self, authorization_code):
        self.authorization_code = authorization_code
        self.token_url = "https://kauth.kakao.com/oauth/token"
        self.user_url  = "https://kapi.kakao.com/v2/user/me"
        self.redirect_url = "http://local:8000/users/kakao/callback"
        
    def get_access_token(self):
        data = {
            'grant_type': 'authorization_code',
            'client_id': settings.KAKAO_APP_KEY,
            'redirect_uri': self.redirect_url,
            'code': self.authorization_code
        }
        response     = requests.post(self.token_url, data)
        access_token = response.json()['access_token']
        return access_token
        
    def get_user_information(self, access_token):
        header = {
            "Authorization" : f'Bearer {access_token}',
            "Content-type"  : "application/x-www-form-unlencoded;charset=utf-8"
        }
        
        user_info = requests.get(self.user_url, headers = header)

        return user_info.json()
 
class KakaoSignView(View):
    def get(self, request):
        auth_code    = request.GET.get('code')
        access_token = KakaoAPI(auth_code).get_access_token()
        user_info    = KakaoAPI(auth_code).get_user_information(access_token)
        kakao_id  = user_info['id']
        nickname  = user_info['kakao_account']['profile']['nickname']
        email     = user_info['kakao_account']['email']
        
        user, created = User.objects.get_or_create(
            kakao_id = kakao_id, defaults = {'name' : nickname, 'email':email}
            )   
             
        token = jwt.encode({'id':user.id}, settings.SECRET_KEY, algorithm=settings.ALGORITHM)

        if created:
            return JsonResponse({"message" : "CREATED", "token" : token}, status = 201)
        
        return JsonResponse({"message" : "SIGNED_IN", "token" : token}, status = 200)