六、python Django REST framework[认证、权限、限流]

django 3.2.13

一、认证

解释:认证有五大认证类: BasicAuthenticationSessionAuthenticationTokenAuthenticationRemoteUserAuthentication,他们都继承了BaseAuthentication

认证流程代码:

1. 先通过分发进入认证环节  def dispatch(self, request, *args, **kwargs):[rest_framework.views.py大约485行前后]
2. 先通过request = self.initialize_request(request, *args, **kwargs)来获得一个新的request,里面已经读取过了配置信息,知道下面要用什么认证方式
3. 该函数里面self.initial(request, *args, **kwargs)进入认证、权限、限流功能
4. initial里面的self.perform_authentication(request)进行认证
5. perform_authentication实际调用user()[rest_framework.requests.py大约220行前后]
6. 由user里面的_authenticate进入到user_auth_tuple = authenticator.authenticate(self)这里开始的authenticate[rest_framework.authentication.py]开始根据配置选择认证方式

使用方法:

解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

  • 全局配置
    • 写入setting.py文件
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',  # Basic认证
        'rest_framework.authentication.SessionAuthentication',  # session认证
        'rest_framework.authentication.TokenAuthentication',  # session认证
        'rest_framework.authentication.RemoteUserAuthentication',  # session认证
    )
}
  • 局部配置
    • 写入views.py
from rest_framework.authentication import SessionAuthentication, BasicAuthentication

class TestGenericAPIView(ModelViewSet):
    authentication_classes = (SessionAuthentication, BasicAuthentication) # 写在这里
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

1.基础认证

1.1 BasicAuthentication

认证方式原理:这种方式不需要Cookie和Session,只需要客户端发起请求的时候,在头部Header中提交用户名和密码(base64格式加密)。如果没有附加,会弹出一个对话框,要求输入用户名和密码。但是它不提供信息加密措施,通常都是以base64编码传输。

好处:简单,不需要Cookie和Session,被广泛支持,一般用于内网比如路由器验证之类

缺点:不安全不能保存信息,关闭浏览器即失效,不能自己退出,比较落后,信息很容易被篡改,目前并不是特别推荐使用

源码简单分析:

# 承接上面最初的第5步,开始根据配置选择认证方式
1. 认证方式[rest_framework.authentication.py]的BasicAuthentication的authenticate()函数
2. 在authenticate()里面调用auth = get_authorization_header(request).split()
3. get_authorization_header()开始去获取header传来关于名称和密码的md5数据
4. 在下面return self.authenticate_credentials(userid, password, request)[大约87]调用self.authenticate_credentials()
5. 其中这个函数里面的authenticate()[大约98]开始查询数据库验证密码

1.2 SessionAuthentication

配置:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
    ],
}

session和cookie:cookie是储存在用户端即浏览器里面,session储存在服务器里面,cookie因为在用户端所以安全差,而且储存内容少,所以把关键内容写入到服务器专门创建的session表里面。当用户第一次请求,服务器就会在session表单里面写入(多个浏览器一个用户,算多次请求,过期或者退出,session可能会消失[依据不同处理逻辑来定]),之后每次请求都会验证是否第一次请求,如果不是则服务器会确定用户操作

认证方式原理:比如用户登录之类都是用其来实现,其是通过验证用户登录后服务器发送给session表单新创建的id号写入cookie(里面有字段为),请求时携带着cookie,提取到服务器去获取cookie里面session的id然后去找到服务器里面的session表去获取里面储存的信息,获取用户身份信息进行验证。Django默认是这种方式

优点:cookie能长期保存能退出,自主加密比较安全

缺点:cookie不能跨域,服务器数据库保存cookie数据,用户多,服务器储存session压力压力大

源码简单分析:

# 承接上面最初的第5步,开始根据配置选择认证方式
1. 通过user = getattr(request._request, 'user', None)获取request._request属性
2. user属性相当于去获取requests.user这个方法相当于去读取cookie解密session并且去数据库里面提取出,当前的用户。

1.3 TokenAuthentication

介绍:未来再介绍

1.4 RemoteUserAuthentication

介绍:未来再介绍

二、权限

基础认证类:

  • AllowAny 允许所有用户
  • IsAuthenticated 仅通过认证的用户
  • IsAdminUser 仅管理员用户
  • IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取

使用方法:

解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

  • 全局配置
    • 写入setting.py文件
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}
  • 局部配置
    • 写入views.py
from rest_framework.authentication import SessionAuthentication, BasicAuthentication

class TestGenericAPIView(ModelViewSet):
    authentication_classes = (SessionAuthentication, ) # 认证方法选择
    permission_classes = (IsAuthenticated,) # 关键在这
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

自定义权限
导入:from rest_framework.permissions import BasePermission
解释:需要继承BasePermission,并重写has_permission'或者Falsehas_object_permission两个方法即可

区别:has_permission 是用户可以对这个视图有没有 GET POST等权限进行区分,has_object_permission 是 has_permission返回True后,再判断这个用户有没有对一个具体的对象有没有操作权限

class IsOwnerOrReadOnly(BasePermission):
    def has_permission(self, request, view):
        if request.method =="DELETE":
            return True
        elif request.method =="GET":
            return True
        else:
            return False

    def has_object_permission(self, request, view, obj):
        return False

注意:关于has_object_permission()没有执行,通过翻看源码。①通过继承ModelViewSet类(里面又继承CreateModelMixin、UpdateModelMixin等等这些类,不知道看上篇文章),UpdateModelMixinRetrieveModelMixinDestroyModelMixin这三个类(做数据库变动操作和单一查询操作),其会在每次执行前调用self.get_object()该方法用来检查其是否存在,以及是否有操作权限(这就是关键),其在里面调用 self.check_object_permissions(self.request, obj)check_object_permissions又调用自己写的has_object_permission;②自己写修改、删除、单一查询要调用self.get_object()该方法,下面展示一段UpdateModelMixin的源代码方便学习self.get_object怎么用

class RetrieveModelMixin:
    """
    Retrieve a model instance.
    """
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

三、限流

缺陷: 部署到服务器之后,因为启动多个uwsgi进程,所以可能会导致一个进程一段缓存,也就是说,下面的限制会不起效(因为下面的限流基于缓存,不同的进程不一样的缓存)
基础限制类:

  • AnonRateThrottle 限制未登录用户

  • UserRateThrottle 限制登录用户

  • ScopedRateThrottle 具体视图限制

使用方法:

解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

  • 限制登录与未登录

导入:from rest_framework.throttling import UserRateThrottle

# 当使用登录与未登录限制的时候,所有视图的访问都会被记录在内
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day', # 未登录用户一天访问最多100次,anon是默认的
        'user': '1000/day'# 登录用户一天访问最多1000次
    } # 可以使用 second, minute, hour 或day来指明周期
}
class TestGenericAPIView(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    throttle_classes = (UserRateThrottle,) # 关键
  • 限制具体视图
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.ScopedRateThrottle', # 让其靠上先生效
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day', # 未登录用户一天访问最多100次,anon是默认的
        'user': '10/hour', # 登录用户一天访问最多1000次
        'do':'3/hour' # 关键
    },

}
class TestGenericAPIView(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    throttle_classes = (UserRateThrottle,) # 不加默认也有主要靠setting.py里面
    throttle_scope = 'do' # 单独视图限流关键
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值