# 1.JWT 安装配置

  • 安装 JWT
pip install djangorestframework-jwt==1.11.0
  • settings.py 配置 jwt 载荷中的有效期设置
# jwt 载荷中的有效期设置
JWT_AUTH = {
    # 1.token 前缀:headers 中 Authorization 值的前缀
    'JWT_AUTH_HEADER_PREFIX': 'JWT',
    # 2.token 有效期:一天有效
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    # 3. 刷新 token:允许使用旧的 token 换新 token
    'JWT_ALLOW_REFRESH': True,
    # 4.token 有效期:token 在 24 小时内过期,可续期 token
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(hours=24),
    # 5. 自定义 JWT 载荷信息:自定义返回格式,需要手工创建
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.views.jwt_response_payload_handler',
}
  • settings.py 配置默认的认证方式
REST_FRAMEWORK = {
    # 认证器
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',  # 在 DRF 中配置 JWT 认证
    ],
}
  • settings.py 配置自定义验证后端登录
AUTHENTICATION_BACKENDS = [
    'app01.views.Manylogin'
]
  • settings.py 注册用户模型
AUTH_USER_MODEL = 'app01.User'

# 2. 重写 Django 用户模型

  • models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# 用户表
class User(AbstractUser):
    username = models.CharField(max_length=50,unique=True)
    password = models.CharField(max_length=255)
    email = models.CharField(max_length=255,null=True,blank=True)
    phone = models.CharField(max_length=255,null=True,blank=True)
    class Meta:
        db_table = 'tb_user'

# 3. 生成 Token

  • utils.py
from rest_framework_jwt.settings import api_settings
def creare_token(user):
    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)
    return token

# 4. 序列化器

  • serializers.py
from .models import *
from rest_framework import serializers
from django.contrib.auth.hashers import make_password
from .utils import creare_token
class CreateUserSerializers(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()
    email = serializers.CharField(allow_null=True)
    phone = serializers.CharField()
    token = serializers.CharField(read_only=True)
    def create(self, validated_data):
        user = User.objects.create(**validated_data)
        password = make_password(validated_data.get('password'))
        user.password = password
        user.save()
        token = create_token(user)
        user.token = token
        return user

# 5. 注册接口

  • views.py
from django.db.models import Q
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import *
from . import models
from django.contrib.auth.backends import ModelBackend
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
class UserView(APIView):
    def post(self, request):
        data = request.data
        print(data)
        if not all(['username', 'password', 'password2', 'email', 'phone']):
            return Response({'code': 202, 'msg': '参数不全'})
        if data['password'] != data['password2']:
            return Response({'code': 204, 'msg': '两次密码不一致'})
        try:
            user = CreateUserSerializers(data=data)
            user.is_valid()
            user.save()
            return Response({'code': 200, 'msg': '创建用户成功', 'data': user.data})
        except Exception as e:
            return Response({'code': 201, 'msg': '创建失败,请重试'})
  • urls.py
from django.urls import path
from app01 import views
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    path('register/', views.UserView.as_view()),
]
  • Postman 测试

# 6. 登录及多形式登录

  • views.py
def jwt_response_payload_handler(token, user=None, request=None):
    return {
        'authenticated': 'true',
        'id': user.id,
        'username': user.username,
        'phone':user.phone,
        'email': user.email,
        'token': token,
    }
# 多形式登录
class Manylogin(ModelBackend):
    # 重写 authenticate 方法
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(username=username) | Q(phone=username) | Q(email=username))
            if user is not None and user.check_password(password):
                return user
        except Exception as e:
            print(e)
            return None
  • urls.py
from django.urls import path
from app01 import views
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    path('register/', views.UserView.as_view()),  
    path('login/', obtain_jwt_token),
]
  • Postman 测试登录

  • Postman 测试多形式登录

# 7. 携带 token 访问所有用户

  • serializers.py
class UserInfoSerializers(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id','username','phone','email')
  • views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import *
from . import models
from rest_framework.permissions import IsAuthenticated
class UserInfoView(APIView):
    # 认证用户才可访问
    permission_classes = [IsAuthenticated]
    def get(self, request):
        user = User.objects.all()
        obj = UserInfoSerializers(user, many=True)
        return Response({'code': 200, 'msg': '查询成功', "data": obj.data})
  • urls.py
from django.urls import path
from app01 import views
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    path('register/', views.UserView.as_view()), 
    path('login/', obtain_jwt_token),
    path('get_user/', views.UserInfoView.as_view()),
]
  • Postman 测试

更新于

请我喝[茶]~( ̄▽ ̄)~*

Daniel ✨ 微信支付

微信支付

Daniel ✨ 支付宝

支付宝