美文网首页
Django rest framework 身份和权限验证

Django rest framework 身份和权限验证

作者: 河码匠 | 来源:发表于2021-07-27 09:52 被阅读0次

    一、身份验证

    rest framwork 默认验证

    1. BasicAuthentication

    此认证方案使用 HTTP 基本认证,针对用户的用户名和密码进行认证。一般登录都是单独写的方法,很少用这个。

    认证成功提供以下信息
    request.user 将是一个 Django User 实例。
    request.auth 将是 None

    2. TokenAuthentication

    基于Token的HTTP认证方案。Token认证适用于客户端 - 服务器设置。
    这个 token 是在 heard 头里面的格式如下

    Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
    
    设置

    a. 设置在 setting.pyINSTALLED_APPS 中添加 rest_framework.authtoken
    b. 执行 manage.py migrate 生成 token 相关的表

    如何创建 token
    from rest_framework.authtoken.models import Token
    
    token = Token.objects.create(user=user_obj)
    

    如何生效请看 三

    3. 自定义验证

    继承 BaseAuthentication

    a. 修改 .authenticate(self, request) 方法完成自定义验证

    该方法返回 (user, auth) 元组或 None

    b. 修改 .authenticate_header(self, request)

    如果实现该方法,则应返回一个字符串,该字符串将用作 HTTP 401 Unauthorize 响应中的 WWW-Authenticate 头的值

    如果 .authenticate_header() 方法未被重写,则认证方案将在未验证的请求被拒绝访问时返回 HTTP 403 Forbidden 响应

    示例

    from django.contrib.auth.models import User
    from rest_framework import authentication
    from rest_framework import exceptions
    
    class ExampleAuthentication(authentication.BaseAuthentication):
        def authenticate(self, request):
            username = request.META.get('X_USERNAME')
            if not username:
                return None
    
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                raise exceptions.AuthenticationFailed('No such user')
    
            return (user, None)
    

    4. 重构 TokenAuthentication 添加 token 过期

    以下是使用 rest_framework.authtoken 的 token 添加一个过期的验证

    from datetime import datetime
    from rest_framework.authentication import TokenAuthentication
    from rest_framework import exceptions
    
    
    class AdminTokenAuthentiation(TokenAuthentication):
        def authenticate_credentials(self, key):
            model = self.get_model()
            try:
                token = model.objects.select_related('user').get(key=key)
            except model.DoesNotExist:
                raise exceptions.AuthenticationFailed('Invalid token.')
    
            if not self.check_token_timeout(token):
                raise exceptions.AuthenticationFailed('Token timeout is invalid.')
    
            if not token.user.is_active:
                raise exceptions.AuthenticationFailed(
                    'User inactive or deleted.')
    
            return (token.user, token)
    
        def check_token_timeout(self, token):
            delta = datetime.now() - token.created
            if delta.total_seconds() < 3600:
                return True
            return False
    

    二、权限验证

    rest framwork 默认权限

    1. AllowAny

    权限类将允许不受限制的访问,而不管该请求是否已通过身份验证或未经身份验证。

    2. IsAuthenticated

    权限类将拒绝任何未经身份验证的用户的权限,并允许其他权限。 如果你希望你的 API 仅供注册用户访问,则此权限适用。

    3. IsAdminUser

    除非 user.is_staffTrue,否则IsAdminUser权限类将拒绝任何用户的权限,在这种情况下将允许权限。

    4. IsAuthenticatedOrReadOnly

    将允许经过身份验证的用户执行任何请求。只有当请求方法是“安全”方法(GET, HEAD 或 OPTIONS)之一时,才允许未经授权的用户请求。

    5. DjangoModelPermissions

    此权限类与 Django 的标准 django.contrib.auth 相关联。此权限只能应用于具有.queryset属性集的视图。只有在用户通过身份验证并分配了相关模型权限的情况下,才会被授予权限。

    自定义权限

    继承 BasePermission

    a. 重写 .has_permission(self, request, view)

    b. 重写 .has_object_permission(self, request, view, obj)

    区别:
    has_permission 在请求进来的时候就开始了属于DRF的三大认证,返回 True 就能访问,False 就禁止访问
    has_object_permissions 是对某个对象的访问权限,

    如果请求被授予访问权限,方法应该返回True,否则返回False。

    \color{red}{注意}: 仅当视图级 has_permission 检查已通过时,才会调用实例级 has_object_permission 方法

    三、设置验证或权限

    1. 全局设置 setting.py
    REST_FRAMEWORK = {
        # 权限
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        )
        # 身份验证
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',
            'rest_framework.authentication.SessionAuthentication',
        )
    }
    
    2. 在 View 类中设置
    def BaseView(generics.GenericAPIView):
        authentication_classes = (AdminTokenAuthentiation, )
        permission_classes = (permissions.IsAuthenticated, AdminOperatingPermission, )
    

    相关文章

      网友评论

          本文标题:Django rest framework 身份和权限验证

          本文链接:https://www.haomeiwen.com/subject/lgiwmltx.html