当前位置:   article > 正文

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

django rest framework authorization

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]开始根据配置选择认证方式
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用方法:

解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(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认证
    )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 局部配置
    • 写入views.py
from rest_framework.authentication import SessionAuthentication, BasicAuthentication

class TestGenericAPIView(ModelViewSet):
    authentication_classes = (SessionAuthentication, BasicAuthentication) # 写在这里
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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
  • 3
  • 4
  • 5
  • 6

1.2 SessionAuthentication

配置:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
    ],
}
  • 1
  • 2
  • 3
  • 4
  • 5

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
  • 2
  • 3

1.3 TokenAuthentication

介绍:未来再介绍

1.4 RemoteUserAuthentication

介绍:未来再介绍

二、权限

基础认证类:

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

使用方法:

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

  • 全局配置
    • 写入setting.py文件
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 局部配置
    • 写入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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

自定义权限
导入: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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

注意:关于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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

三、限流

缺陷: 部署到服务器之后,因为启动多个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来指明周期
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
class TestGenericAPIView(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    throttle_classes = (UserRateThrottle,) # 关键
  • 1
  • 2
  • 3
  • 4
  • 限制具体视图
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' # 关键
    },

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
class TestGenericAPIView(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    throttle_classes = (UserRateThrottle,) # 不加默认也有主要靠setting.py里面
    throttle_scope = 'do' # 单独视图限流关键
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/479534
推荐阅读
相关标签
  

闽ICP备14008679号