美文网首页
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