zoukankan      html  css  js  c++  java
  • 前后端分离认证 认证使用JWT

    认证分类

    认证分为 RBAC与Auth  而我们Django就是RBAC

    那么什么是RBAC呢? 就是基于角色的访问控制

    而这种表设置分为 3表 5表 6表

    表设计

     5表产生原因 多对多的原因

     

    一种是用户破格拥有某种权限,不依赖身份 表

    这个是django的表

    对应着身份与权限以及用户的对应关系 表示哪些用户是哪个分组 哪些权限

    权限表分析注意事项

    因为user里面还有其他字段 需要继承,并告诉DJango 使用自己的user表

    当时如果数据库迁移后 就无法再使用了 所以一定要在迁移之前进行继承AsbrUser

    JWT

    虽然认证不用去数据库校验session,但是服务器遇到登陆注册的时候 还是需要生成session并保存,也是需要io操作 

    还得去校验session  所以我们就索性不去校验了

     

    所以有了第二种 JWT

    你给我的信息 我通过算法给你生成一个token ,你下次来请求我,你把token带上

    你下次请求我的时候 带上这个token 我进行解密,如果没有问题 我就给您通过

    jwt缺点

    一旦JWT签发,在有效期内将会一直有效

    JWT使用

    #下载
    pip install djangorestframework-jwt
    
    #post请求登陆成功 返回token
    from django.urls import path
    from rest_framework_jwt.views import obtain_jwt_token
    urlpatterns = [
        path('login/', obtain_jwt_token),
    ]

    #使用自己的返回token方法 import datetime JWT_AUTH = { # 过期时间 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), # 自定义认证结果:见下方序列化user和自定义response 'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.utils.jwt_response_payload_handler', }

    自定义返回token  (可以再自己的util模块写因为这是公共的)

    from .serializers import UserModelSerializers
    def jwt_response_payload_handler(token, user=None, request=None):
        return {
            'token': token,
            'user': UserModelSerializer(user).data
        }
    from rest_framework import serializers
    from .models import User
    class UserModelSerializer(serializers.ModelSerializer):
        """轮播图序列化器"""
        class Meta:
            model = User
            fields = ["username", "mobile"]

    开始认证user/authentications.py(自己创建)

    import jwt
    from rest_framework.exceptions import AuthenticationFailed
    from rest_framework_jwt.authentication import jwt_decode_handler
    from rest_framework_jwt.authentication import get_authorization_header
    from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
    class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):
            def authenticate(self, request):
                # 采用drf获取token的手段 - HTTP_AUTHORIZATION - Authorization
                token = get_authorization_header(request)
                if not token:
                    raise AuthenticationFailed('Authorization 字段是必须的')
                # 可以添加反扒措施:原功能是token有前缀
    
                # drf-jwt认证校验算法
                try:
                    payload = jwt_decode_handler(token)
                except jwt.ExpiredSignature:
                    raise AuthenticationFailed('签名过期')
                except jwt.InvalidTokenError:
                    raise AuthenticationFailed('非法用户')
                user = self.authenticate_credentials(payload)
                # 将认证结果丢该drf
                return user, token

    全局配置 局部配置

    REST_FRAMEWORK = {
        # 认证模块
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'user.authentications.JSONWebTokenAuthentication',
        ),
    }

    # 局部禁用
    authentication_classes = []

    
    

    # 局部启用
    from user.authentications import JSONWebTokenAuthentication
    authentication_classes = [JSONWebTokenAuthentication]

     

    多方式登录

    配置

    AUTHENTICATION_BACKENDS = ['user.utils.JWTModelBackend']
    from django.contrib.auth.backends import ModelBackend
    from .models import User
    import re
    class JWTModelBackend(ModelBackend):
        def authenticate(self, request, username=None, password=None, **kwargs):
            """
            :param request:
            :param username: 前台传入的用户名
            :param password: 前台传入的密码
            :param kwargs:
            :return:
            """
            try:
                if re.match(r'^1[3-9]d{9}$', username):
                    user = User.objects.get(mobile=username)
                elif re.match(r'.*@.*', username):
                    user = User.objects.get(email=username)
                else:
                    user = User.objects.get(username=username)
            except User.DoesNotExist:
                return None  # 认证失败就返回None即可,jwt就无法删除token
            # 用户存在,密码校验通过,是活着的用户 is_active字段为1
            if user and user.check_password(password) and self.user_can_authenticate(user):
                return user  # 认证通过返回用户,交给jwt生成token

      

  • 相关阅读:
    Spring----->projects----->Spring IO Platform(也即spring的BOM:Bill Of Materials)
    可添加功能-----机器学习管理平台
    Maven--->学习心得--->maven的Dependency Mechanism(依赖关系机制)
    Maven--->使用实例
    Maven--->学习心得--->maven的相关配置---->概述 以及 相关配置实例
    Maven--->学习心得--->maven的配置文件settings.xml
    netty学习记录(实例)
    netty学习记录
    打开CKeditor默认本地上传
    Spring Security 报There is no PasswordEncoder mapped for the id "null"
  • 原文地址:https://www.cnblogs.com/xzqpy/p/11209544.html
Copyright © 2011-2022 走看看