0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Django]トークン認証にdjango-rest-knoxを利用する

Last updated at Posted at 2024-04-13

はじめに

自分用の個人開発のメモ/備忘録として記録していきます。

環境

django5.0
↓ dockerでの開発環境作成はこちら

↓ 認証ユーザーモデルはこちらをそのままそのまま利用

やりたいこと

簡単に有効期限を設定したトークン認証を実装したい
トークンだけじゃなく、他の情報も取得出来るようにしたい

djangorestframework-simplejwtと比較したい

導入

インストール

pipでインストール

pip install django-rest-knox

settings.pyの設定変更

・INSTALLED_APPSに rest_framework と knox を追加
・全てのviewをトークン認証にするためDEFAULT_AUTHENTICATION_CLASSESを設定
・Knoxの有効期限、自動更新を設定

settings.py
INSTALLED_APPS = (
  ...
  'rest_framework',
  'knox',
  ...
)

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'knox.auth.TokenAuthentication',
    ],
}

REST_KNOX = {
    "TOKEN_TTL": timedelta(hours=2),    # 有効期限を2時間に設定する
    'AUTO_REFRESH': True,    # トークンの自動更新を有効にする
}

serializers.py作成

・認証用 email/password のLoginSerializer作成
・レスポンス用の UserSerializer作成

serializers.py
from rest_framework import serializers
from users.models import CustomUser


class LoginSerializer(serializers.ModelSerializer):
    email = serializers.EmailField()

    class Meta:
        model = CustomUser
        fields = ["email", "password"]

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ["id", "email", "name"]

views.py作成

・トークン認証のみにするため、こちらを参考にLoginViewをオーバーライド
・認証出来たらログインも実行
・有効期限ではなくユーザー情報を返却出来るように「get_post_response_data」をオーバーライド

views.py
from rest_framework import permissions
from django.contrib.auth import authenticate, login
from knox.views import LoginView as KnoxLoginView
from users.serializers import LoginSerializer, UserSerializer
from rest_framework import status
from rest_framework.response import Response

class LoginView(KnoxLoginView):
    permission_classes = (permissions.AllowAny,)

    def get_post_response_data(self, request, token, instance):
        return {
            'user': UserSerializer(instance.user).data,
            'token': token
        }

    def post(self, request, format=None):
        serializer = LoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = authenticate(
            request=request,
            username=serializer.validated_data["email"],
            password=serializer.validated_data["password"],
        )
        if user is not None:
            login(request, user)
            return super(LoginView, self).post(request, format=None)
        else:
            return Response(
                data={"error": "email or password is incorrect"},
                status=status.HTTP_400_BAD_REQUEST,
            )

urls.py作成

・オーバーライドしたLoginViewを設定
・ログアウトはデフォルトをそのまま利用

urls.py
from django.urls import path
from knox import views as knox_views
from users.views import LoginView

urlpatterns = [
    path(r'login/', LoginView.as_view(), name='knox_login'),
    path(r'logout/', knox_views.LogoutView.as_view(), name='knox_logout'),
    path(r'logoutall/', knox_views.LogoutAllView.as_view(), name='knox_logoutall'),
]

アクセスしてみる

ログインで無事ユーザーデータも取得OK
image.png

ログアウトも無事成功
image.png

image.png

おわりに

・比較的簡単に導入できた
・リフレッシュトークンもデフォルトで利用できたら嬉しかった

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?