• drf-rest_framework-jwt相关


    1.安装

    pip install djangorestframework-jwt

    2.创建超级用户,一步一步往填写,账户,密码,确认密码,若是弱密码,会问你"密码很弱,希望继续使用吗?(Y/N)",肯定是输入 y继续

    3.然后就可以利用后台进行普通,或者其他用户的创建等操作了

     4.配置路由 urls.py文件

    from app_jwt import views
    from django.urls import path, re_path
    from rest_framework_jwt.views import obtain_jwt_token
    
    urlpatterns = [
        path('login/', obtain_jwt_token),
    ]

    这里我使用了路由分发

     

     进行 postman访问 成功

     若是使用自居 带的进行访问的话 要在头上 加点东西

    发送访问请求(必须带jwt空格)

     配置文件 settings.py中书写自己写的 自动签发与过期时间等设置

    import datetime
    
    JWT_AUTH = {
        'JWT_RESPONSE_PAYLOAD_HANDLER': 'app_jwt.utils.my_jwt_response_payload_handler',  # 这里的是我自己的app的文件里自己书写的
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),  # 过期时间,手动配置
    }
    from app_jwt.utils import my_jwt_response_payload_handler # 用这句话的能保用 词不会错,因为在配置文件中不会补全.
    明显 是 app_jwt项目 下面有个 utils.py文件中 有个 类或者 方法叫
     my_jwt_response_payload_handler  我这里是个方法

    下面书写自定义的文件的代码
    def my_jwt_response_payload_handler(token, user=None, request=None):
        return {
            'status': 100,
            'msg': "ok",
            'data': {
                'token': token,
            }
        }
    这里的代码 是 自己写返回些什么内容 ,若是使用自带的话就只会返回一个token

     若是想要全局认证的话 自己写一个认证 类 配置settings.py文件

    REST_FRAMEWORK = {
        # 认证模块
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'users.app_jwt.utils.MyJwt',
        ),
    }

    下面是我自己定义的认证类

    from rest_framework_jwt.utils import jwt_decode_handler
    from rest_framework_jwt.authentication import BaseAuthentication
    import jwt
    from rest_framework.exceptions import AuthenticationFailed
    from api import models
    
    
    class MyJwt(BaseAuthentication):
        def authenticate(self, request):
            jwt_value = request.META.get('HTTP_AUTHORIZATION')
            if jwt_value:
                try:
                    payload = jwt_decode_handler(jwt_value)
                except jwt.ExpiredSignatureError:
                    raise AuthenticationFailed('签名过期!')
                except jwt.InvalidTokenError:
                    raise AuthenticationFailed('用户不合法!')
                except Exception as e:
                    raise AuthenticationFailed(str(e))
                user = models.User.objects.get(pk=payload.get('user_id'), username=payload.get('username'))
                return user, jwt_value
            raise AuthenticationFailed('您未携带token认证信息!')
    from django.shortcuts import render
    
    # Create your views here.
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app_jwt import serializer
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    from rest_framework.permissions import IsAuthenticated
    
    from .utils import MyJwt
    
    
    class GoodsAPIView(APIView):
        authentication_classes = [] # 配置了全局的话,局部禁用加上这句就可以了
        authentication_classes = [MyJwt] # 未配置全局的话,局部使用 加上这句 后面是自己定义的认证类
        permission_classes = [IsAuthenticated] # 都要配合权限认证一块儿使用
    
        def get(self, request, *args, **kwargs):
            return Response('good信息!')

    多方式登录,(用户名/手机号/邮箱)

    视图文件 views.py

    class LoginView(ViewSet):
        def login(self, request, *args, **kwargs):
            login_serializer = serializer.LoginModelSerializer(data=request.data)
            login_serializer.is_valid(raise_exception=True)
            token = login_serializer.context.get('token')
            return Response({'status': 200, 'msg': '登录成功!', 'token': token, })

    序列化器 serializer.py

    class LoginModelSerializer(serializers.ModelSerializer):
        username = serializers.CharField()
    
        class Meta:
            model = models.User
            fields = ['username', 'password']
    
        def validate(self, attrs):
            username = attrs.get('username')
            password = attrs.get('password')
            import re
            if re.match('^1[3-9][0-9]{9}$', username):
                user = models.User.objects.filter(mobile=username).first()
            elif re.match('^.*@.*$', username):
                user = models.User.objects.filter(email=username).first()
            else:
                user = models.User.objects.filter(username=username).first()
    
            if user:
                if user.check_password(password):
                    payload = jwt_payload_handler(user)
                    token = jwt_encode_handler(payload)
                    self.context['token'] = token
    
                    return attrs
                else:
                    raise ValidationError('密码错误!')
            else:
                raise ValidationError('账户不存在!')

    路由文件 urls.py

    from app_jwt import views
    from django.urls import path, re_path
    from rest_framework_jwt.views import obtain_jwt_token
    
    urlpatterns = [
        path('login/', obtain_jwt_token),
        path('test/', views.TestAPIView.as_view()),
        path('goods/', views.GoodsAPIView.as_view()),
        #登录相关   
        path('login1/', views.LoginView.as_view({'post': 'login'})),
        path('login2/', views.Login2View.as_view({'post': 'login'})),
    
    
    
    ]

    也可以把 序列化器中的相关逻辑语句写在视图文件中像这样:

    class Login2View(ViewSet):
        def login(self, request, *args, **kwargs):
            username = request.data.get('username')
            password = request.data.get('password')
            import re
            if re.match('^1[3-9][0-9]{9}$', username):
                user = models.User.objects.filter(mobile=username).first()
            elif re.match('^.*@.*$', username):
                user = models.User.objects.filter(email=username).first()
            else:
                user = models.User.objects.filter(username=username).first()
            if user:
                if user.check_password(password):
                    payload = jwt_payload_handler(user)
                    token = jwt_encode_handler(payload)
                    return Response({'status': 200, 'msg': '登录成功!', 'token': token, })
                raise ValidationError('密码错误 !')
            raise ValidationError('账户不存在!')

    逻辑是从上往下走的,所以在还没有返回数据之前,写在哪里都是可以的.

  • 相关阅读:
    个人知识库建设:搜集、归类、整理、提纯
    vue学习:定义全局变量并使用
    flask学习:配置https请求
    flask项目部署到云服务器,并通过域名访问后端服务
    微信小程序开发学习系列
    shell数组
    RabbitMQ安装与基本原理
    bootstrap强化模态窗口插件
    多选框插件
    2022全国卷乙卷文科数学解析版|图片
  • 原文地址:https://www.cnblogs.com/xiao-zang/p/13308273.html
Copyright © 2020-2023  润新知