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

posted @ 2022-06-29 13:36  太晓  阅读(98)  评论(0编辑  收藏  举报