drf 三大认证详解

目录

  • drf 三大认证:

    • 认证:
    • 权限:
      • 认证与权限组件绑定使用:
    • 频率:
      • 多方式登录:

drf 三大认证:

认证:

# 全局配置:
    -在全局(认证组件只能决定request.user,不是断定权限的地方,所以一般配置全局)

REST_FRAMEWORK = {
    # 认证组件
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
    ],
}

# 局部禁用(login 模块):

authentication_classes = ''
permission_classes = ''

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
# authentication_classes = [JSONWebTokenAuthentication]

#自定义认证类:
    1) 如果使用session认证,drf默认提供了SessionAuthentication
    2) 如果使用drf-jwt认证框架,drf-jwt框架提供了JSONWebTokenAuthentication
    3) 如果是自定义签发与校验token,才需要将校验token的算法封装到自定义的认证类中

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        """
        1) 从请求头中拿到前台提交的token(一般从HTTP_AUTHORIZATION中拿,也可以与前台约定)
              -- 如果设置了反爬等措施,校验一下反爬(头 token)
        2)没有token,返回None,代表游客
        3)有token,进入校验
              -- 不通过:抛AuthenticationFailed异常,代表非法用户
              -- 通过:返回 (user, token),代表合法用户
        """
        pass

#认证规则:
    认证组件:校验用户 - 游客、合法用户、非法用户
    游客:代表校验通过,直接进入下一步校验(权限校验)
    合法用户:代表校验通过,将用户存储在request.user中,再进入下一步校验(权限校验)
    非法用户:代表校验失败,抛出异常,返回403权限异常结果
    只要通过认证不管是游客还是登录用户,request.user都有值

权限:

#drf 自带权限组件:
    IsAuthenticated, IsAdminUser, AllowAny, IsAuthenticatedOrReadOnly

#自定义:
自定义权限类:
1) drf默认提供了一些权限类
    AllowAny:游客和登录用户有全权限
    IsAuthenticated:只有登录用户有全权限
    IsAdminUser:只有后台用户(admin用户)有全权限
    IsAuthenticatedOrReadOnly:游客有读权限,登录用户有全权限
2)如果有特殊需要,需要自定义权限类
    如:只有superuser有权限、只有vip用户有权限、只有某ip网段用户有权限、只有某个视图及其子类有权限
    根据需求,request和view的辅助,制定权限规则判断条件

默认权限:
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
'DEFAULT_PERMISSION_CLASSES': [
    'rest_framework.permissions.AllowAny',
],

#permissions.py (vip 分组权限管理)
from rest_framework.permissions import BasePermission
class MyAPIView(APIView):
    permission_classes = [permissions.VIPUserPermission]

class VIPUserPermission(BasePermission):  # 只要vip分组用户有权限
    def has_permission(self, request, view):
        for group in request.user.groups.all():
            if group.name.lower() == 'vip':
                return True  # 有权限
        return False  # 无权限

认证与权限组件绑定使用:

    1)每一个视图类都要进行认证校验,且认证规则一致,所以全局配置认证类即可
    2)每一个视图类都要进行权限校验,默认配置的是不限制(AllowAny),但实际开发中,视图类的访问权限不尽相同,所以要在具体
        的视图类,配置具体的权限规则

from rest_framework.viewsets import ViewSet
class UserViewSet(ViewSet):
    # 权限:只有VIP用户可以查看个人详细详细
    permission_classes = [permissions.VIPUserPermission]

    def retrieve(self, request, *args, **kwargs):
        return APIResponse(results={
            'username': request.user.username,
            'email': request.user.email,
            'mobile': request.user.mobile,
            'data_joined': request.user.date_joined,
        })

频率:

from rest_framework.throttling import SimpleRateThrottle
"""
自定义频率类
1) drf默认提供了一些频率类
    AnonRateThrottle:只对游客进行频率限制
    UserRateThrottle:对所有用户进行频率限制
2)如果有特殊需要,需要自定义频率类
    如:对ip进行限次、对电话进行限制、对视图某些信息进行限次
"""
class MobileRateThrottle(SimpleRateThrottle):
    """
    1)设置scope字符串类属性,同时在settings中进行drf配置DEFAULT_THROTTLE_RATES
        eg: DEFAULT_THROTTLE_RATES = {'mobile': '1/min'}
    2)重写get_catch_key方法:
        返回与限制条件有关的字符串,表示限制
        返回None,表示不限制
    """
    scope = 'mobile'
    def get_cache_key(self, request, view):
        if not request.user.is_authenticated or not request.user.mobile:
            return None  # 匿名用户 或 没有电话号的用户 都不限制

        # 只要有电话号的用户踩进行限制
        return self.cache_format % {
            'scope': self.scope,
            'ident': request.user.mobile
        }

多方式登录:

from rest_framework.views import APIView
class LoginAPIView(APIView):
    """ 重点
    1)token只能由 登录接口 签发
    2)登录接口也是APIView的子类,使用一定会进行 认证、权限 组件的校验
    结论:不管系统默认、或是全局settings配置的是何认证与权限组件,登录接口不用参与任何认证与权限的校验
    所以,登录接口一定要进行 认证与权限 的局部禁用
    """
    authentication_classes = []
    pagination_class = []

    def post(self, request, *args, **kwargs):
        serializer = serializers.LoginModelSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)  # 内部在全局钩子中完成token的签发
        return APIResponse(results={
            'username': serializer.content.get('user').username,
            'token': serializer.content.get('token')
        })

#serializer.py

from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
import re
class LoginModelSerializer(serializers.ModelSerializer):
    # post请求,序列化默认当做create动作进行校验,需要校验数据库,create动作username会抛用户已存在异常
    # 抛用户已存在异常是多余的,所以自定义系统校验规则即可
    username = serializers.CharField(min_length=3, max_length=16)
    password = serializers.CharField(min_length=3, max_length=16)
    class Meta:
        model = models.User
        fields = ('username', 'password')

    # 用全局钩子,完成token的签发
    def validate(self, attrs):
        # 1)通过 username 和 password 完成多方式登录校验,得到user对象
        user = self._validate_user(attrs)
        # 2)user对象包装payload载荷
        payload = jwt_payload_handler(user)
        # 3)payload载荷签发token
        token = jwt_encode_handler(payload)
        # 4)将user与token存储到serializer对象中,方便在视图类中使用
        self.content = {
            'user': user,
            'token': token
        }
        return attrs

    def _validate_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')

        if re.match(r'.*@.*', username):  # 邮箱
            user = models.User.objects.filter(email=username).first()  # type: models.User
        elif re.match(r'^1[3-9][0-9]{9}$', username):  # 电话
            user = models.User.objects.filter(mobile=username).first()
        else:  # 用户名
            user = models.User.objects.filter(username=username).first()

        if not user or not user.check_password(password):
            raise serializers.ValidationError({'message': '用户信息异常'})

        return user

自定义签发token :

    1)将请求数据交给序列化类,执行序列化校验
    2)在序列化全局校验钩子中,完成user的认证与token的签发,保存在序列化对象的content中
    3)在视图类中从序列化对象的content中拿user与token相关信息返回
    注:多方式登录体现在 请求的账号类型可能是用户名、邮箱或手机等,采用不同字段校验数据库即可

原文地址:https://www.cnblogs.com/shaozheng/p/12141576.html

时间: 2024-11-11 23:17:56

drf 三大认证详解的相关文章

Linux中pam认证详解(下)

Linux中pam认证详解(下) 在上一篇中详细的介绍了pam的介绍.pam认证原理.pam认证构成以及pam验证控制类型,下面向大家详细介绍一下常用的pam服务模块,以及pam认证的应用. 一.常用的pam服务模块 下面是Linux提供的PAM模块列表(只是其中一部分),这其中包含模块文件.模块功能描述和相关配置文件,具体如下: pam_access 提供logdaemon风格登录控制 /etc/security/access.conf pam_chroot 提供类似chroot命令的功能 p

C# 网络编程之豆瓣OAuth2.0认证详解和遇到的各种问题及解决

        最近在帮人弄一个豆瓣API应用,在豆瓣的OAuth2.0认证过程中遇到了各种问题,同时自己需要一个个的尝试与解决,最终完成了豆瓣API的访问.作者这里就不再吐槽豆瓣的认证文档了,毕竟人家也不容易.但是作者发现关于豆瓣OAuth认证过程的文章非常之少,所以想详细写这样一篇文章方便后面要做同样东西的人阅读.希望文章对大家有所帮助,尤其是想做豆瓣API开发的初学者. (文章中蓝色字表示官方文档引用,红色字是可能遇到问题及注意,黑色字是作者叙述) 一.误区OAuth1.0认证过程    

Mysql 三大特性详解

Mysql 三大特性详解 Mysql Innodb后台线程 工作方式 首先Mysql进程模型是单进程多线程的.所以我们通过ps查找mysqld进程是只有一个. 体系架构 InnoDB存储引擎的架构如下图所以,是由多个内存块组成的内存池,同时又多个后台线程进行工作,文件是存储磁盘上的数据. 后台线程 上面看到一共有四种后台线程,每种线程都在不停地做自己的工作,他们的分工如下: Master Thread: 是最核心的线程,主要负责将缓冲池中的数据异步刷新的磁盘,保证数据的一致性,包括脏页的刷新.合

?DRF?-----三大认证组件--认证组件

认证组件 铺垫: 源码分析 入口: restframework 框架内的 views 下的 APIView 的 dispatch方法 组件的最下面 有三个方法   分别是 认证组件  权限组件 和 频率组件 perform_authentication (认证组件) 校验用户 - 游客 合法用户 非法用户 游客: 代表校验通过 进入下一步校验 (权限校验) 合法用户: 代表校验通过 将用户 存储在 request.user 中 再进行下一步校验 非法用户: 代表校验失败 抛出异常 返回403 权

drf三大认证

源码分析 dispath方法内 self.initial(request, *args, **kwargs) 进入三大认证 # 认证组件:校验用户(游客,合法用户,非法用户) # 游客:代表校验通过直接进入下一步校验, # 合法用户:代表校验通过,将用户存储在request.user中,在进入下一步校验 # 非法用户:代表校验失败,抛出异常,返回403权限异常结果 self.perform_authentication(request) # 权限组件:校验用户权限,必须登录,所有用户登录读写,游

drf三大认证:认证组件-权限组件-权限六表-自定义认证组件的使用

三大认证工作原理简介 源码分析: from rest_framework.views import APIView 源码分析入口: 内部的三大认证方法封装: 三大组件的原理分析: 权限六表分析 基于用户权限访问控制的认证(RBAC):Role-Based-Access-Control;基于auth的认证规则(了解). Django框架采用的是RBAC认证规则:通常分为:三表规则.五表规则.Django采用的是六表规则. 三表:用户表.角色表.权限表 五表:用户表.角色表.权限表.用户角色关系表.

drf三大认证补充

频率认证 源码分析部分 def check_throttles(self, request): for throttle in self.get_throttles(): if not throttle.allow_request(request, self): self.throttled(request, throttle.wait()) def throttled(self, request, wait): #抛异常,可以自定义异常,实现错误信息的中文显示 raise exceptions

Shrio认证详解+自定义Realm

Authentication(身份认证)是Shiro权限控制的第一步,用来告诉系统你就是你. 在提交认证的时候,我们需要给系统提交两个信息: Principals:是一个表示用户的唯一属性,可以是用户名,邮箱之类的. Credentials:是证明用户身份的证书,可以是密码或者指纹之类的. 认证主要分为三步: 1.收集认证信息 2.提交认证信息 3.如果认证成功,则允许访问,否则就拒绝访问或者重试. 收集认证信息: 在入门的例子中,使用了一个UsernamePasswordToken来收集用户的

SVN子命令diff三大用法详解

主要介绍SVN子命令diff的用法 检查历史修改的详情:SVN子命令 diff-使用标准区别文件格式显示区别,它在提交前用来显示本地工作拷贝与版本库的区别. 事实上,SVN子命令diff有三种不同的用法:1. 检查本地修改 2. 比较工作拷贝与版本库 3. 比较版本库与版本库 比较本地修改:像我们看到的,不使用任何参数调用时,svn diff将会比较你的工作文件与缓存在.svn的"原始"拷贝:$ svn diffIndex: rules.txt=====================