认证分类
认证分为 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