一、身份验证
身份验证是将传入请求与一组识别凭证相关联的机制。
例如请求携带的用户名密码,签名令牌等。然后权限之类的限制策略才可以使用这些凭证来确定是否应该允许请求。
身份验证始终在视图的最开始运行,在权限和限制检查发生之前,在任何其他代码被允许继续之前。
REST框架提供多种开箱即用的身份验证方案,后面项目实战时,我们再讨论。
1.1 当登录成功之后,跳转到其他url的配置
二、权限验证
与身份验证,限流一起,权限决定是否应该授予或拒绝访问请求。
权限检查总是在视图的最开始运行,在任何其他代码被允许继续之前。权限检查通常会使用request.user
和request.auth
属性中的身份验证信息来确定是否应允许传入请求。
权限用于授予或拒绝不同类别的用户访问 API 的不同部分。
最简单的权限是允许任何经过身份验证的用户访问,而拒绝任何未经身份验证的用户访问。
三、如何确定权限
REST framework
中权限被定义为权限列表。在运行视图的主体之前,检查列表中的每个权限。如果任何权限检查失败,将引发exceptions.PermissionDeniedorexceptions.NotAuthenticated
异常,并且视图的主体将不会运行。当权限检查失败时,将根据以下规则返回“403 Forbidden”或“401 Unauthorized”响应:
- 请求已成功验证,但权限被拒绝。— 将返回 HTTP 403 Forbidden 响应。
- 请求未成功通过身份验证,最高优先级的身份验证类没有使用WWW-Authenticate标头。— 将返回 HTTP 403 Forbidden 响应。
- 请求的身份验证没有成功,并且最高优先级的身份验证类使用了WWW-Authenticate头。— 将返回HTTTP 401 Unauthorized响应。
四、如何设置权限?
附:内置权限
AllowAny
允许任何请求访问。
IsAuthenticated
只允许通过身份验证的请求访问。
IsAdminUser
只允许管理员身份的请求访问。
IsAuthenticatedOrReadOnly
只允许通过身份验证的请求或者只读请求(get,head,option)访问
也就说:通过认证的用户有写权限,没有通过认证的用户只有读权限
4.1【设置全局权限】:
可以使用设置全局设置默认权限策略DEFAULT_PERMISSION_CLASSES
。例如。
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
如果未指定,此设置默认为允许不受限制的访问:
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
4.2【设置视图权限】
您还可以使用基于APIView
类的视图,在每个视图或每个视图集的基础上设置权限策略
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
class ExampleView(APIView):
permission_classes = [IsAuthenticated]
或者使用基于装饰器@api_view
的函数视图
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
pass
注意:直接在视图上设置权限类列表后,会忽略设置【settings.py
】文件中配置的权限类列表。
4.3 自定义权限
要实现自定义权限,需要继承BasePermission
类并实现以下方法中的一个或两个:
- .
has_permission(self, request, view)
- .
has_object_permission(self, request, view, obj)
如果请求被授予访问权限,则该方法应返回True,否则返回False。
注意
对象级的has_object_permission
方法只有在视图级的has_permission
检查已经通过的情况下才会被调用。
如果测试失败,自定义权限应该引发一个PermissionDenied
异常。若要更改与异常关联的错误消息,请在自定义权限上直接实现message
属性。否则,将使用PermissionDenied的default_detail
属性。类似地,要更改与异常相关的代码标识符,请直接在自定义权限上实现一个code
属性——否则将使用PermissionDenied的default_code
属性。
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
message = 'Adding customers not allowed.'
def has_permission(self, request, view):
...
4.4 对象级权限
REST 框架权限还支持对象级权限。对象级权限用于确定是否应允许用户对特定对象进行操作,该对象通常是模型实例。
对象级权限由REST框架的通用视图调用get_object
时运行。与视图级别权限一样,也有例外。如果不允许用户对给定对象进行操作,则会引发PermissionDenied
异常。
如果您正在编写自己的视图并希望强制执行对象级权限,或者覆盖了通用视图上的get_object
方法,那么您需要在视图方法中显示的调用check_object_permissions(request, obj)
五、项目实战
为了讲清楚身份验证与权限,我们再创建一个应用projects
设计模型如下:
class Project(models.Model):
name = models.CharField('项目名称', max_length=20, help_text='项目名称')
desc = models.CharField('项目描述', max_length=200, help_text='项目描述', null=True, blank=True)
leader = models.ForeignKey('auth.User', verbose_name='项目负责人', on_delete=models.SET_NULL, null=True, help_text='项目负责人')
c_time = models.DateTimeField('创建时间', auto_now_add=True)