安裝配置
pip install djangorestframework-jwt
配置setting

########### 1、在INSTALLED_APPS中加入'rest_framework.authtoken', ################# INSTALLED_APPS = [ ''' 'rest_framework.authtoken', # ''' ] ################### 2、配置jwt驗證 ###################### REST_FRAMEWORK = { # 身份認證 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ), #全局配置JWT驗證設置 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), } import datetime JWT_AUTH = { 'JWT_AUTH_HEADER_PREFIX': 'JWT', 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), 'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.views.jwt_response_payload_handler', # 重新login登錄返回函數 } AUTH_USER_MODEL='users.User' # 指定使用users APP中的 model
配置全局路由

from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ path('admin/', admin.site.urls), re_path(r'users/',include(('users.urls','users'),namespace='users')) ]
配置局部路由

#! /usr/bin/env python # -*- coding: utf-8 -*- from django.urls import path,re_path,include from users import views from rest_framework_jwt.views import obtain_jwt_token # 驗證密碼后返回token urlpatterns = [ path('v1/register/', views.RegisterView.as_view(), name='register'), # 注冊用戶 path('v1/login/', obtain_jwt_token,name='login'), # 用戶登錄后返回token path('v1/list/', views.UserList.as_view(), name='register'), # 測試需要攜帶token才能訪問 ]
重寫User表

from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): username = models.CharField(max_length=64, unique=True) password = models.CharField(max_length=255) phone = models.CharField(max_length=64) token = models.CharField(max_length=255)
設置序列化器

#! /usr/bin/env python # -*- coding: utf-8 -*- from rest_framework_jwt.settings import api_settings from rest_framework import serializers from users.models import User class UserSerializer(serializers.Serializer): username = serializers.CharField() password = serializers.CharField() phone = serializers.CharField() token = serializers.CharField(read_only=True) def create(self, data): user = User.objects.create(**data) user.set_password(data.get('password')) user.save() # 補充生成記錄登錄狀態的token jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) user.token = token return user
代碼實現

from django.shortcuts import render import json from rest_framework.views import APIView from rest_framework.views import Response from rest_framework.permissions import IsAuthenticated from rest_framework_jwt.authentication import JSONWebTokenAuthentication from users.serializers import UserSerializer # 用戶注冊 class RegisterView(APIView): def post(self, request, *args, **kwargs): serializer = UserSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400) # 重新用戶登錄返回函數 def jwt_response_payload_handler(token, user=None, request=None): ''' :param token: jwt生成的token值 :param user: User對象 :param request: 請求 ''' return { 'token': token, 'user': user.username, 'userid': user.id } # 測試必須攜帶token才能訪問接口 class UserList(APIView): permission_classes = [IsAuthenticated] # 接口中加權限 authentication_classes = [JSONWebTokenAuthentication] def get(self,request, *args, **kwargs): print(request.META.get('HTTP_AUTHORIZATION', None)) return Response({'name':'zhangsan'}) def post(self,request, *args, **kwargs): return Response({'name':'zhangsan'})
全局配置接口需要jwt驗證

#jwt設置 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ), #配置全部接口需要驗證才能發訪問,驗證方式為登陸用戶 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), }
局部接口解除jwt驗證要求

class RegisterView(APIView): # 在此接口中允許所有用戶訪問,去除jwt的驗證要求 permission_classes = [AllowAny] def post(self, request, *args, **kwargs): serializer = UserSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400)
自定義驗證方式:要求手機或者郵箱也可作為登陸手段

AUTHENTICATION_BACKENDS = [ 'userapp.views.UsernameMobileAuthBackend', ]

from django.db.models import Q from django.contrib.auth.backends import ModelBackend #驗證基類 class UsernameMobileAuthBackend(ModelBackend): #重寫驗證方式 def authenticate(self, request, username=None, password=None, **kwargs): user = MyUser.objects.get(Q(username=username) | Q(phone=username)) if user is not None and user.check_password(password): return user
根據jwt逆向解析出用戶信息
from rest_framework_jwt.utils import jwt_decode_handler user_obj = jwt_decode_handler(token)