diadia

興味があることをやってみる。自分のメモを残しておきます。

authtokenをrestframeworkだけで実装して観察してみる

昔Token認可で実装したことがあるけど、rest-authを使って実装したのでライブラリを使わないで試してみる。

ドキュメント

https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication

settings.py

まず、Tokenで認可させたい場合Tokenテーブルが必要なんだけど、これはrestframework.authtoken.modelsにTokenモデルがある。 したがってINSTALLED_APPSにrestframework.authtokenを加える必要がある。

# settings.pyにて
# Application definition
DJANGO_CONTRIB_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    # 'django.contrib.sessions',  # ステートレス通信のため削除
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

THIRD_PARTY_APPS = [
    'rest_framework',
    'rest_framework.authtoken'  # Tokenテーブルを作成するためのアプリか? JWTを使うときも必要か?
]

ORIGINAL_APPS = [
    "observe_login"
]
INSTALLED_APPS = DJANGO_CONTRIB_APPS + THIRD_PARTY_APPS + ORIGINAL_APPS


#  ステートレス通信のため
#  'django.contrib.sessions.middleware.SessionMiddleware', 
# は不要だと思っていたが、削除するとエラーが出てしまったため残しておく。
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

https://github.com/encode/django-rest-framework/blob/master/rest_framework/authtoken/models.py

views.py

class SignInAPIView(APIView):
    def get(self, request, *args, **kwargs):
        # ログインデータテンプレートを表示する
        return Response({'username': '', 'password': ''})

    def post(self, request, *args, **kwargs):
        ''' ユーザー認証した場合にはtokenを返す '''
        username = request.data['username']
        password = request.data['password']
        user_obj = authenticate(username=username, password=password)
        if user_obj is None:
            return Response({'result': 'credential is not valid'})
        try:
            # クライアントにセットするためtokenを出力する
            token = Token.objects.get(user=user_obj.id)
            return Response({"result": "success", 'tokenKey': token.key})
        except:
            return Response({'result': 'token fail'})


class SignUpAPIView(APIView):
    def get(self, request, *args, **kwargs):
        # 送信データテンプレートを表示する
        return Response(data={'username': '', 'password': ''}, status=200)

    # User登録と同時に当該UserにTokenをセット、発行する
    def post(self, request, *args, **kwargs):
        serializer = UserModelSerializer(data=request.data)
        if not serializer.is_valid():
            return Response({"result": "fail"})
        username = serializer.validated_data['username']
        password = serializer.validated_data["password"]
        user_obj = User.objects.create_user(
            username=username, password=password)
        token = Token.objects.create(user=user_obj)
        print("TOKEN KEY : ", token.key)
        # クライアントにセットするためtokenを出力する
        return Response({"result": "success", "tokenKey": token.key})

受け取ったtokenを使う

cookieやlocalStorageを操作するには? - diadia