安装配置
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[![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0);)