Django 基于 rest_framework 的 jwt 用户身份验证, 附带分页
参考
https://pythondjango.cn/
requirement
django==3.2
djangorestframework==3.13.1
djangorestframework-jwt==1.11.0
pycryptodome==3.14.1
settings.py
# 替换用户模型
AUTH_USER_MODEL = 'app_user.AuthUser'
# 添加 rest_framework 应用
INSTALLED_APPS = [
...
'corsheaders',
'rest_framework',
'app_user',
]
# 添加 rest_framework 配置
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
],
# 分页模块
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
# JWT配置
JWT_AUTH = {
# 指明token的有效期
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
# 允许刷新
'JWT_ALLOW_REFRESH': True,
# JWT头
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
# 'JWT_SECRET_KEY': "emlYhMkNU38jXSRQdz7BCZFWxJr6DyaP",
}
view_login.py
import math
from django.contrib.auth.hashers import check_password
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_jwt.settings import api_settings
from common.common import Result
from app_user.models import AuthUser
from app_article.models import Article
def jwt_token_generate(user):
"""
基于rest_framework_jwt生成jwt token
"""
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
# 往请求头的 authorization 中需要添加的 token 数据,
# 此数据前需加 settings 中配置的 JWT头 再加一个空格
payload = jwt_payload_handler(user)
# 生成对token进行加密
token = jwt_encode_handler(payload)
return token
class Result:
"""
响应内容封装
"""
@staticmethod
def success(msg="success", data="success"):
return {
"data": data,
"code": 200,
"msg": msg
}
@staticmethod
def fail(msg='fail', data='fail'):
return {
"data": data,
"code": 500,
"msg": msg
}
@staticmethod
def paged(pager: PageNumberPagination, data, msg="success"):
return {
"data": data,
"code": 200,
"msg": msg,
"page": {'data_count': pager.page.paginator.count,
'page_count': math.ceil(pager.page.paginator.count / pager.page_size),
'page_size': 10,
'page_current': pager.page.number,
}
}
class UserLogin(APIView):
'''
用户登陆接口
'''
# 禁用身份验证
authentication_classes = []
permission_classes = []
def post(self, request):
"""
@params:
@username:登录账号,可以是用户名/手机号
@password:登录密码
"""
# 数据完整校验
if not request.POST.get('username'):
return Response(Result.fail(msg='请填写用户名'))
if not request.POST.get('password'):
return Response(Result.fail(msg='请填写密码'))
username = request.POST.get('username')
password = request.POST.get('password')
# 读用户信息
user = AuthUser.objects.get(username=username)
# 密码验证
if not check_password(password, user.password):
return Response(Result.fail(msg='密码错误'))
# jwt token 前端存入 session 即可通过身份验证
token = jwt_token_generate(user)
result = Result.success(msg='登录成功')
result['token'] = token
return Response(result)
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer,Serializer
class ArticleListSerializer(ModelSerializer):
article_create_time = serializers.DateTimeField(
format="%Y-%m-%d %H:%M:%S", read_only=True)
def to_representation(self, instance):
data = super().to_representation(instance)
return data
class Meta:
model = Article
fields = '__all__'
from rest_framework.pagination import PageNumberPagination
class UserArticleList(APIView):
'''
业务接口
'''
def get(self, request):
'''
业务 get 请求处理
@params:
@page: 页码
'''
# 取jwt保存的用户id
user_id = request.user.id
# 业务数据
article_list = Article.objects.filter(article_user_id=user_id)
# 分页器
pager = PageNumberPagination()
article_list = pager.paginate_queryset(queryset=article_list,
request=request, view=self)
serializer = ArticleListSerializer(instance=article_list, many=True)
pager.get_paginated_response(serializer.data)
return Response(Result.paged(pager=pager, data=serializer.data))
models.py
略
urls.py
略