1. 程式人生 > 程式設計 >DRF使用simple JWT身份驗證的實現

DRF使用simple JWT身份驗證的實現

前言

在Django的前後端分離專案中DRF(Django Restframe Work)框架無疑是首選,關於token驗證一般使用的是JWT,但是JWT只支援到Django1.x的版本。

官方推薦Django2.x之後的版本使用simple JWT,官方文件。

登入返回token和refresh

user 模型類:

我user模型類繼承的是django.contrib.auth.models.AbstractUser,這樣可以使用Django自帶的認證。

如果繼承該類,我們就必須在settings中配置 AUTH_USER_MODEL = "users.UserProfile"

from datetime import datetime

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.

class UserProfile(AbstractUser):
  """
  使用者
  """
  name = models.CharField(max_length=30,null=True,blank=True,verbose_name="姓名")
  birthday = models.DateField(null=True,verbose_name="出生年月")
  gender = models.CharField(max_length=6,choices=(("male",u"男"),("female","女")),default="female",verbose_name="性別")
  mobile = models.CharField(null=True,max_length=11,verbose_name="電話")
  email = models.CharField(max_length=100,verbose_name="郵箱")

  class Meta:
    verbose_name = "使用者"
    verbose_name_plural = "使用者"

  def __str__(self):
    return self.username

序列化檔案:

注意這裡使用的User是Django管理的user模型類,要從django.contrib.auth.get_user_model例項化獲取。

users模組的serializers.py檔案中寫如下序列化類繼承自rest_framework_simplejwt.serializers.TokenObtainPairSerializer

在這裡插入圖片描述

from django.contrib.auth import get_user_model
User = get_user_model()

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
  @classmethod
  def get_token(cls,user):
    token = super().get_token(user)
    token['name'] = user.username
    return token

  def validate(self,attrs):
    """
    登入返回token和refresh
    :param attrs:
    :return:
    """
    data = super().validate(attrs)
    data['token'] = str(data["access"])
    return data

根據官方文件的說明,get_token方法之所以設定token['name']是因為程式可能執行在叢集上,這裡不寫也可以。

編寫檢視類

from users.serializers import MyTokenObtainPairSerializer

class MyTokenObtainPairView(TokenObtainPairView):
  serializer_class = MyTokenObtainPairSerializer

編寫url:

其中api/token/api/token/refresh/兩個URL是simple JWT自帶的token方法:

  • api/token/
    用於獲取token
  • api/token/refresh/用於重新整理token
from django.conf.urls import url
from django.urls import include,path

from rest_framework_simplejwt.views import (
  TokenObtainPairView,TokenRefreshView,)

urlpatterns = [
  # simple jwt 認證介面
  path('api/token/',TokenObtainPairView.as_view(),name='token_obtain_pair'),path('api/token/refresh/',TokenRefreshView.as_view(),name='token_refresh'),path('login/',MyTokenObtainPairView.as_view(),]

settings配置SIMPLE_JWT:

這是對token的一些自定義設定包括獲取的token和refresh的生命週期等配置,通過檢視rest_framework_simplejwt的原始碼可以發現有很多自定義配置,感興趣的小夥伴可以通過檢視官方文件瞭解更多,這裡我只配置了獲取的token的生命週期。

啟動程式訪問:

在這裡插入圖片描述

在這裡插入圖片描述

可以發現返回了三個值:

  • refresh:是重新整理token用的,當前端token過期需要重新整理token的時候就可以訪問前邊說的api/token/refreshurl,引數就是refresh的值。
  • access:這個就是token但是框架裡叫做access。
  • token:這個是在序列化檔案中給access新命名了一個值,方便前端獲取:
def validate(self,attrs):
  """
  登入返回token和refresh
  :param attrs:
  :return:
  """
  data = super().validate(attrs)
  data['token'] = str(data["access"])
  return data

註冊返回token

檢視類:

  • 在檢視類中匯入from rest_framework_simplejwt.tokens import RefreshToken
  • 重寫create方法,需要通過前邊匯入的RefreshToken來獲取token返回給前端。
from django.contrib.auth import get_user_model
from django.db.models import Q
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.mixins import CreateModelMixin
from rest_framework import viewsets
from rest_framework import status

from users.serializers import (
  UserRegSerializer
)
from .models import VerifyCode

User = get_user_model()


class UserViewSet(CreateModelMixin,viewsets.GenericViewSet):
  """
  使用者
  """
  serializer_class = UserRegSerializer
  queryset = User.objects.all()

  def create(self,request,*args,**kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    user = self.perform_create(serializer)

    ret_dict = serializer.data
    refresh = RefreshToken.for_user(user)
    access_token = str(refresh.access_token)
    ret_dict["token"] = access_token

    headers = self.get_success_headers(serializer.data)
    return Response(ret_dict,status=status.HTTP_201_CREATED,headers=headers)

  def perform_create(self,serializer):
    return serializer.save()

到此這篇關於DRF使用simple JWT身份驗證的實現的文章就介紹到這了,更多相關DRF使用simple JWT身份驗證內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!