drf框架 8 系统权限类使用 用户中心信息自查 token刷新机制 认证组件项目使用:多方式登录 权限组件项目使用:vip用户权限 频率组件 异常组件项目使用

系统权限类使用

图书接口:游客只读,用户可增删改查权限使用

from rest_framework.permissions import IsAuthenticatedOrReadOnly
class BookViewSet(ModelViewSet):
    # 游客只读,用户可增删改查
    permission_classes = [IsAuthenticatedOrReadOnly]

    queryset = models.Book.objects.all()
    serializer_class = serializers.BookSerializer

特殊路由映射的请求

实现用户中心信息自查,不带主键的get请求,走单查逻辑

urls.py
# 用路由组件配置,形成的映射关系是 /user/center/ => list  |  user/center/(pk)/ => retrieve
# router.register(‘user/center‘, views.UserCenterViewSet, ‘center‘)

urlpatterns = [
    # ...
    # /user/center/ => 单查,不能走路由组件,只能自定义配置映射关系
    url(‘^user/center/$‘, views.UserCenterViewSet.as_view({‘get‘: ‘user_center‘})),
]
views.py
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
class UserCenterViewSet(GenericViewSet):
    permission_classes = [IsAuthenticated, ]
    queryset = models.User.objects.filter(is_active=True).all()
    serializer_class = serializers.UserCenterSerializer

    def user_center(self, request, *args, **kwargs):
        # request.user就是前台带token,在经过认证组件解析出来的,
        # 再经过权限组件IsAuthenticated的校验,所以request.user一定有值,就是当前登录用户
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)

token刷新机制(了解)

drf-jwt直接提供刷新功能

"""
1)运用在像12306这样极少数安全性要求高的网站
2)第一个token由登录签发
3)之后的所有正常逻辑,都需要发送两次请求,第一次是刷新token的请求,第二次是正常逻辑的请求
"""
settings.py
import datetime

JWT_AUTH = {
    # 配置过期时间
    ‘JWT_EXPIRATION_DELTA‘: datetime.timedelta(minutes=5),

    # 是否可刷新
    ‘JWT_ALLOW_REFRESH‘: True,
    # 刷新过期时间
    ‘JWT_REFRESH_EXPIRATION_DELTA‘: datetime.timedelta(days=7),
}
urls.py
from rest_framework_jwt.views import ObtainJSONWebToken, RefreshJSONWebToken
urlpatterns = [
    url(‘^login/$‘, ObtainJSONWebToken.as_view()),  # 登录签发token接口
    url(‘^refresh/$‘, RefreshJSONWebToken.as_view()),  # 刷新toekn接口
]
Postman
# 接口:/api/refresh/
# 方法:post
# 数据:{"token": "登录签发的token"}

认证组件项目使用:多方式登录

urls.py
# 自定义登录(重点):post请求 => 查操作(签发token返回给前台) - 自定义路由映射
url(‘^user/login/$‘, views.LoginViewSet.as_view({‘post‘: ‘login‘})),
views.py
# 重点:自定义login,完成多方式登录
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
class LoginViewSet(ViewSet):
    # 登录接口,要取消所有的认证与权限规则,也就是要做局部禁用操作(空配置)
    authentication_classes = []
    permission_classes = []

    # 需要和mixins结合使用,继承GenericViewSet,不需要则继承ViewSet
    # 为什么继承视图集,不去继承工具视图或视图基类,因为视图集可以自定义路由映射:
    #       可以做到get映射get,get映射list,还可以做到自定义(灵活)
    def login(self, request, *args, **kwargs):
        serializer = serializers.LoginSerializer(data=request.data, context={‘request‘: request})
        serializer.is_valid(raise_exception=True)    # 会根据post方法默认完成create入库检验,校验唯一约束字段
        token = serializer.context.get(‘token‘)
        return Response({"token": token})
serializers.py
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler

# 重点:自定义login,完成多方式登录
class LoginSerializer(serializers.ModelSerializer):
    # 登录请求,走的是post方法,默认post方法完成的是create入库校验,所以唯一约束的字段,会进行数据库唯一校验,导致逻辑相悖
    # 需要覆盖系统字段,自定义校验规则,就可以避免完成多余的不必要校验,如唯一字段校验
    username = serializers.CharField()
    class Meta:
        model = models.User
        # 结合前台登录布局:采用账号密码登录,或手机密码登录,布局一致,所以不管账号还是手机号,都用username字段提交的
        fields = (‘username‘, ‘password‘)

    def validate(self, attrs):
        # 在全局钩子中,才能提供提供的所需数据,整体校验得到user
        # 再就可以调用签发token算法(drf-jwt框架提供的),将user信息转换为token
        # 将token存放到context属性中,传给外键视图类使用
        user = self._get_user(attrs)
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        self.context[‘token‘] = token
        return attrs

    # 多方式登录
    def _get_user(self, attrs):
        username = attrs.get(‘username‘)
        password = attrs.get(‘password‘)
        import re
        if re.match(r‘^1[3-9][0-9]{9}$‘, username):
            # 手机登录
            user = models.User.objects.filter(mobile=username, is_active=True).first()
        elif re.match(r‘^[email protected]+$‘, username):
            # 邮箱登录
            user = models.User.objects.filter(email=username, is_active=True).first()
        else:
            # 账号登录
            user = models.User.objects.filter(username=username, is_active=True).first()
        if user and user.check_password(password):
            return user

        raise ValidationError({‘user‘: ‘user error‘})

权限组件项目使用:vip用户权限

数据准备
"""
1)User表创建两条数据
2)Group表创建一条数据,name叫vip
3)操作User和Group的关系表,让1号用户属于1号vip组
"""
permissions.py
from rest_framework.permissions import BasePermission

from django.contrib.auth.models import Group
class IsVipUser(BasePermission):
    def has_permission(self, request, view):
        if request.user and request.user.is_authenticated:  # is_authenticated必须是合法用户
            try:
                vip_group = Group.objects.get(name=‘vip‘)
                if vip_group in request.user.groups.all():  # 用户可能不属于任何分组
                    return True  # 必须是vip分组用户
            except:
                pass

        return False
views.py
from .permissions import IsVipUser
class CarViewSet(ModelViewSet):
    permission_classes = [IsVipUser]

    queryset = models.Car.objects.all()
    serializer_class = serializers.CarSerializer
serializers.py
class CarSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Car
        fields = (‘name‘, )
urls.py
router.register(‘cars‘, views.CarViewSet, ‘car‘)

频率组件

重点
"""
1)如何自定义频率类
2)频率校验的规则
3)自定义频率类是最常见的:短信接口一分钟只能发生一条短信
"""
自定义频率类
"""
1)自定义类继承SimpleRateThrottle        (或者设定全局变量,views中直接调用,下面给案列)
2)设置类实现scope,值就是一个字符串,与settings中的DEFAULT_THROTTLE_RATES进行对应
    DEFAULT_THROTTLE_RATES就是设置scope绑定的类的频率规则:1/min 就代表一分钟只能访问一次
3)重写 get_cache_key(self, request, view) 方法,指定限制条件
    不满足限制条件,返回None:代表对这类请求不进行频率限制
    满足限制条件,返回一个字符串(是动态的):代表对这类请求进行频率限制
        短信频率限制类,返回 "throttling_%(mobile)s" % {"mobile": 实际请求来的电话}
"""
系统频率类
#1)UserRateThrottle: 限制所有用户访问频率
#2)AnonRateThrottle:只限制匿名用户访问频率

频率组件项目使用:请求方式频率限制

throttles.py
from rest_framework.throttling import SimpleRateThrottle
# 只限制查接口的频率,不限制增删改的频率
class MethodRateThrottle(SimpleRateThrottle):
    scope = ‘method‘
    def get_cache_key(self, request, view):
        # 只有对get请求进行频率限制
        if request.method.lower() not in (‘get‘, ‘head‘, ‘option‘):
            return None    # 不加以限制

        # 区别不同的访问用户,之间的限制是不冲突的
        if request.user.is_authenticated:    # 有名用户
            ident = request.user.pk
        else:    # 匿名用户
            # get_ident是BaseThrottle提供的方法,会根据请求头,区别匿名用户,
            # 保证不同客户端的请求都是代表一个独立的匿名用户
            ident = self.get_ident(request)
        return self.cache_format % {‘scope‘: self.scope, ‘ident‘: ident} # 设定频率
    # ident 唯一标识
settings.py
REST_FRAMEWORK = {
    #  ...
    # 频率规则配置
    ‘DEFAULT_THROTTLE_RATES‘: {
        # 只能设置 s,m,h,d,且只需要第一个字母匹配就ok,m = min = maaa 就代表分钟
        ‘user‘: ‘3/min‘,  # 配合drf提供的 UserRateThrottle 使用,限制所有用户访问频率
        ‘anon‘: ‘3/min‘,  # 配合drf提供的 AnonRateThrottle 使用,只限制匿名用户访问频率
        ‘method‘: ‘3/min‘,
    },
}
views.py
from .permissions import IsVipUser
from .throttles import MethodRateThrottle
class CarViewSet(ModelViewSet):
    permission_classes = [IsVipUser]
    throttle_classes = [MethodRateThrottle]

    queryset = models.Car.objects.all()
    serializer_class = serializers.CarSerializer

或者在全局变量中设定user,anon频率参数,views中直接调用全局频率设定

# setting.py
REST_FRAMEWORK = {
        # 频率规则配置
    ‘DEFAULT_THROTTLE_RATES‘: {
        # 只能设置 s,m,h,d,且只需要第一个字母匹配就ok,m = min = maaa 就代表分钟
        ‘user‘: ‘3/min‘,  # 配合drf提供的 UserRateThrottle 使用,限制所有用户访问频率
        ‘anon‘: ‘3/min‘,  # 配合drf提供的 AnonRateThrottle 使用,只限制匿名用户访问频率
    },
}

# views.py
from rest_framework.throttling import AnonRateThrottle,UserRateThrottle
class BookViewSet(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.BookSerializer

    permission_classes = [IsAuthenticatedOrReadOnly]  # 配置权限校验,所有用户
    # throttle_classes = [AnonRateThrottle]        # 针对匿名用户
    throttle_classes = [UserRateThrottle]

异常组件项目使用:记录异常信息到日志文件

exception.py
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
def exception_handler(exc, context):
    # 只处理客户端异常,不处理服务器异常,
    # 如果是客户端异常,response就是可以直接返回给前台的Response对象
    response = drf_exception_handler(exc, context)

    if response is None:
        # 没有处理的服务器异常,处理一下
        # 其实给前台返回 服务器异常 几个字就行了
        # 那我们处理异常模块的目的是 不管任何错误,都有必要进行日志记录(线上项目只能通过记录的日志查看出现过的错误)
        response = Response({‘detail‘: ‘%s‘ % exc})

    # 需要结合日志模块进行日志记录的:项目中讲
    return response
settings.py
REST_FRAMEWORK = {
    # ...
    # 异常模块
    # ‘EXCEPTION_HANDLER‘: ‘rest_framework.views.exception_handler‘,  # 原来的,只处理客户端异常
    ‘EXCEPTION_HANDLER‘: ‘api.exception.exception_handler‘,
}

课程小结

"""
1)认证模块:多方式登录
2)权限组件:vip权限认证
3)频率组件:请求方式的频率限制
4)异常组件:目的是记录异常日志

drf整体总结:
1)APIView生命周期:请求解析、响应渲染、异常响应(日志)
2)序列化组件
3)视图家族
4)三大认证
5)群查:搜索、排序、分页、分类、区间
"""

原文地址:https://www.cnblogs.com/ludingchao/p/12364875.html

时间: 2024-08-08 15:28:29

drf框架 8 系统权限类使用 用户中心信息自查 token刷新机制 认证组件项目使用:多方式登录 权限组件项目使用:vip用户权限 频率组件 异常组件项目使用的相关文章

drf框架, 接口(api) Django FBV => CBV drf框架的基础试图类 drf核心组件 群查与单查 python换源

接口 """ 接口概念:前台与后台进行信息交互的媒介 - url链接 接口组成: url链接 - 长得像返回数据的url链接 请求方式 - get(查).post(增).put(整体改).patch(局部改).delete(删) 请求参数 - 拼接参数.数据包参数(urlencoded.form-data.json) 响应结果 - 响应的json数据 """ 开发阶段接口测试工具 """ Postman: 官网下载.

drf框架中jwt认证,以及自定义jwt认证

0909自我总结 drf框架中jwt 一.模块的安装 官方:http://getblimp.github.io/django-rest-framework-jwt/ 他是个第三方的开源项目 安装:pip install djangorestframework-jwt 使用自带设定好的jwt from django.urls import path from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ path(

DRF框架知识总览

DRF框架知识总览 """ 1)接口(api): 什么是接口 接口文档 接口规范 2)FBV => CBV:Function|Class Base View CBV的请求生命周期 CBV比FBV的优势 3)drf框架的基础试图类 APIView:请求模块.解析模块.渲染模块.响应模块.异常模块 4)drf核心组件 序列化组件:将后台的任何数据,进行序列化返回给前台:将前台的数据反序列化成后台model对象再入库 三大认证组件:认证组件.权限组件(RBAC).频率组件 视

啥?多个不同用户中心也能实现单点登录?

随着经营发展和业务需要,企业的信息化系统慢慢开始变多,比如ERP.OA.CRM等.为了有效的管理账号,很多企业建立了用户中心(简称IdP,身份提供方Identity Provider),企业内系统可使用一套账号.企业在持续发展的过程中,也在持续建设新的系统,新的系统有自己的用户中心,那么两个用户中心如何打通?企业用户会不会因为增加新系统而又回到需要记多套密码的时候? 用友的iuap推出的"联邦用户中心",可快速打通企业内用户中心与外部用户中心,实现统一用户管理.身份认证.授权等,达到单

签发token、校验token、多方式登录签发token的实现、自定义认证反爬规则的认证类、admin使用自定义User表:新增用户密码密文、群查接口各种筛选组件数据准备、drf搜索过滤组件、drf排序过滤组件、drf基础分页组件

签发token 源码入口 # 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口 # 1)rest_framework_jwt.views.ObtainJSONWebToken 的 父类 JSONWebTokenAPIView 的 post 方法 # 接收有username.password的post请求 # 2)post方法将请求得到的数据交给 rest_framework_jwt.serializer.JSONWebTokenSerializer 处

DRF框架之视图的扩展类简介

这里呢,我将为大家介绍一下DRF框架,为我们提供的试图扩展类的使用方法即作用. 在使用视图扩展类时,需要将mixins模块导入到view文件中. from rest_framework import mixins 并且,在使用视图扩展类时,必须结合GenericAPIView基类一起使用. 所谓,视图的扩展类,就是GenericAPIView的子类,他们继承自GenericAPIView类,并在此基础上封装了增删改查的功能函数. 模板代码: class BookInfoAPIView(mixin

DRF框架中其他功能:认证、权限、限流

定义视图时,只要视图继承了APIView或其子类,就可以使用DRF框架的认证.权限和限流功能. 当客户端访问API接口时,DRF框架在调用对应的API接口之前,会依次进行认证.权限和限流的操作. 认证Authentication 权限Permissions 限流Throttling 原文地址:https://www.cnblogs.com/oklizz/p/11290731.html

drf框架 6 视图集与路由组件(开发最常用、最高级) 三大认证原理 RBAC认证规则

准备工作 models.py from django.db import models # 基类:是抽象的(不会完成数据库迁移),目的是提供共有字段的 class BaseModel(models.Model): is_delete = models.BooleanField(default=False) updated_time = models.DateTimeField(auto_now_add=True) class Meta: abstract = True # 必须完成该配置 cla

django drf框架中的user验证以及JWT拓展的介绍

登录注册是几乎所有网站都需要去做的接口,而说到登录,自然也就涉及到验证以及用户登录状态保存,最近用DRF在做的一个关于网上商城的项目中,引入了一个拓展DRF JWT,专门用于做验证和用户状态保存.这个拓展比传统的CSRF更加安全.先来介绍一下JWT认证机制吧! Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景.JWT的声明一般被用来在身