DRF 08

目录

  • 三大认证

    • 流程
    • 认证组件
    • 权限组件
    • 频率组件
    • 自定义token的签发

三大认证

流程

  • 由于DRF中, 所有的视图类都要直接和间接继承APIView类, 也只有APIView类中才有dispatch方法, 所以所有的请求都要经过三大认证, 认证通过后执行相应请求的视图函数
def dispatch(self, request, *args, **kwargs):

    "..."   

    try:
        # 三大认证
        self.initial(request, *args, **kwargs)

        "..."   

    except Exception as exc:
            # 异常处理
            response = self.handle_exception(exc)

def initial(self, request, *args, **kwargs):

    "..."   

    # 认证
    self.perform_authentication(request)
    # 权限
    self.check_permissions(request)
    # 频率
    self.check_throttles(request)
  1. 认证组件
  • 请求未携带token ==> 游客
  • 请求携带token
    • token认证通过 ==> 合法用户
    • token认证未通过 ==> 非法用户
  1. 权限组件
  • 游客权限
  • 登录用户权限
  1. 频率组件
  • 限制
  • 不限制

认证组件

  1. DRF认证类的默认配置
# rest_framework/settings.py
'DEFAULT_AUTHENTICATION_CLASSES': [
        # 默认采用的session认证
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication'
  1. 自定义认证类
    1. 继承BaseAuthentication
    2. 重写authenticate方法
    3. 方法体
      1. 从请求头HTTP_AUTHORIZATION中拿token
      2. 没有token返回None, 游客
      3. 有token, 校验不通过, 抛AuthenticationFailed异常, 非法用户
      4. 有token, 校验通过, 返回(user, token), 合法用户
# authentications.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

# 自定义认证类继承BaseAuthentication
class MyAuthentication(BaseAuthentication):
    """
    1.从请求中获取token(一般是HTTP_AUTHORIZATION)
    2.token为None, 返回None, ==> 游客
    3.token不为None
        认证失败, raise AuthenticationFailed(''), ==> 非法用户
        认证通过, 返回(user, token)或者(user, None), ==> 合法用户
    """
    def authenticate(self, request):
        pass
  1. 全局配置认证类
# settings.py
REST_FRAMEWORK = {
    # 全局配置认证类
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'api.authentications.MyAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ]
}

权限组件

  1. DRF权限类的默认配置
# rest_framework/settings.py
'DEFAULT_PERMISSION_CLASSES': [
    # 默认不做权限限制
    'rest_framework.permissions.AllowAny',
    ],

class AllowAny(BasePermission):
    def has_permission(self, request, view):
        return True

"""
DRF默认提供的些权限类:
    AllowAny:游客和登录用户有全权限
    IsAuthenticated:只有登录用户有全权限
    IsAdminUser:只有后台用户(admin用户)有全权限
    IsAuthenticatedOrReadOnly:游客有读权限,登录用户有全权限
"""
  1. 自定义权限类
    1. 继承BasePermission
    2. 重写has_permission方法
    3. 方法体
      1. 根据实际需求设置条件
      2. 返回True, 代表有权限
      3. 返回False, 代表无权限
# permissions.py
from rest_framework.permissions import BasePermission
# vip用户权限
class VipPermission(BasePermission):
    def has_permission(self, request, view):
        for group in request.user.groups.all():
            if group.name.lower() == 'vip':
                return True
        return False
  1. 局部配置权限类
# views.py
# 只有vip用户才能进行单查
class UserViewSet(ViewSet):
    # 局部配置权限类
    permission_classes = [permissions.VipPermission]

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

频率组件

  1. 自定义频率组件

    1. 继承SimpleRateThrottle
    2. 设置 scope=‘xxx‘, xxx 对应的是在settings.py设置的频率 ‘xxx‘: ‘1/min‘
    3. 重写get_cache_key方法
    4. 方法体:
      1. 返回None, 不做限制
      2. 返回self.cache_format, 有频率限行
# throttles.py
from rest_framework.throttling import SimpleRateThrottle

# 自定义频率限制类: 按照手机号限行
class MobileRateThrottle(SimpleRateThrottle):
    scope = 'mobile'

    def get_cache_key(self, request, view):
        # 匿名用户和没有手机号的不做限制
        if not request.user.is_authenticated or not request.user.mobile:
            return None  # 反正None就是不做限制

        return self.cache_format % {
            'scope': self.scope,
            'ident': request.user.mobile
        }
# settings.py
REST_FRAMEWORK = {
    # 频率类一般是局部配置, 但是频率调节在settings.py中配置
    'DEFAULT_THROTTLE_RATES': {
        'user': '5/min',
        'anon': '3/min',
        'mobile': '1/min'
    },
}

自定义token的签发

  • 要实现多方式登录, 一定要自定义token的签发
class LoginModelSerializer(serializers.ModelSerializer):
    username = serializers.CharField(max_length=12, min_length=3)
    password = serializers.CharField(min_length=6)

    class Meta:
        model = models.User
        fields = ('username', 'password')

    # 全局钩子完成token签发
    def validate(self, attrs):
        # 1.获取user对象
        user = self._validate_user(attrs)
        # 2.获取payload
        payload = jwt_payload_handler(user)
        # 3.获取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()
        # 手机号
        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({'msg': '用户名或密码错误'})

        return user

原文地址:https://www.cnblogs.com/bigb/p/12146386.html

时间: 2024-10-08 11:45:44

DRF 08的相关文章

百度哈斯发卡号是减肥哈卡斯加分了卡斯

http://www.ebay.com/cln/ta_ya20/-/167521224015/2015.02.08 http://www.ebay.com/cln/p-m6466/-/167398283011/2015.02.08 http://www.ebay.com/cln/ta_ya20/-/167521242015/2015.02.08 http://www.ebay.com/cln/p-m6466/-/167398294011/2015.02.08 http://www.ebay.co

克同极用后管期果要议向中如极示听适VybVfesyhpR

社保划到税务征收,将大大提升社保费的征管效率.税务的征管能力是目前而言最强的,以后税务征收社保不是代收,属于本职了. 之前税局要把社保信息和交个税的工资比对起来有困难!现在好了,个税是自己的,社保也是自己的,比对困难?不存在的! 这一变革,会给那些不给员工上社保.不全额上社保的企业致命一击! 最新案例 前段时间的发改委关于限制特定严重失信人乘坐民航的一则意见--发改财金[2018]385号,其中还有税务总局的联合署名. http://weibo.com/20180408PP/2309279811

【DRF权限】 -- 2019-08-09 12:08:24

目录 权限的详细用法 原文: http://106.13.73.98/__/66/ 我们都听过权限,那么权限到底是做什么的呢. 我们都有博客,或者去一些论坛,一定知道管理员这个角色, 比如我们申请博客的时候,一定要向管理员申请,也就是说管理员会有一些特殊的权利,是我们没有的. ==这些对某件事情决策的范围和程度,我们叫做权限==,权限是我们在项目开发中经常用到的. 本文将详细讲述DRF框架为我们提供的权限组件的使用方法. @ * 源码剖析** DRF的版本控制.认证.权限.频率组件都在initi

Bootstrap 3.2.0 源码试读 2014/08/09

第一部分 normalize.css 104至110行 code,    /* 编辑代码 */ kbd,    /* 键盘输入的文本 */ pre, samp {    /* 范例,sample的简写 */   font-family: monospace, monospace;    /* 这个地方应该是写错了,第二字体应该是serif */   font-size: 1em; } 设置字体的大小为1em,字体为monospace. 111至119行 button, input, optgro

笔试算法题(08):输出倒数第K个节点

出题:输入一个单向链表,要求输出链表中倒数第K个节点 分析:利用等差指针,指针A先行K步,然后指针B从链表头与A同步前进,当A到达链表尾时B指向的节点就是倒数第K个节点: 解题: 1 struct Node { 2 int v; 3 Node *next; 4 }; 5 Node* FindLastKth(Node *head, int k) { 6 if(head==NULL) { 7 printf("\nhead is NULL\n"); 8 exit(0); 9 } 10 Nod

android插件化-apkplug中OSGI服务基本原理-08

我们提供 apkplug 下OSGI使用demo 源码托管地址为 http://git.oschina.net/plug/OSGIService 一 OSGI与android Service 异同点 OSGI服务与android Service概念差不多也是Service ,Client 关系. android Service接口  --service.AIDL OSGI接口                --java interface 所以android 进程间通信Service只能传递序列

2014年4月23日 10:22:08

step 1 : 做tcp网络编程,要解析一批批的数据,可是数据是通过Socket连接的InputStream一次次读取的,读取到的不是需要转换的对象,而是要直接根据字节流和协议来生成自己的数据对象. 按照之前的编程思维,总是请求然后响应,当然Socket也是请求和响应,不过与单纯的请求响应是不同的. 这里Socket连接往往是要保持住的,也就是长连接,然后设置一个缓冲区,网络流不断的追加到缓冲区.然后后台去解析缓冲区的字节流. http://cuisuqiang.iteye.com/blog/

java进阶08 GUI图形界面

图形化用户界面(GUI) 简而言之,就是可视化编程. 要想实现可视化界面(窗口),需要用到JFrame类. package Frame; public class JFrame1 { public static void main(String[] args){ UI ui=new UI(); } } 先建一个主函数,而主函数中的操作只有一句代码.这样做,既能直观又方便后期修改. 接下来是UI类的实现 package Frame; import javax.swing.JFrame; publi

2017/08/21 工作日志

今天先战略放弃了下拉列表的问题,但是后来在园子得到了一个答案,不过忘记去试验了,在家也无法测试,明天试着解决一下. 上午先把机构代码和地区代码的取值显示改了一下,然后将原来只在一个iframe里的弹框扩大到完整的页面,原理是把参照目标设为父窗口,这个之前也猜到了. 接着在改表头颜色的问题上耽误了一段时间.这里的问题是如果通过GridView自动生成数据,就不会有thead,这样就不能单独设置样式,解决的手段有几种,这里有篇帖子http://www.cnblogs.com/JavCof/archi