在介绍Django REST Framework(二):Request和Response 时提到,DRF提供了对身份验证和权限的处理机制,特点如下:
在这篇文章中,将对身份验证和权限进行总结。使用时需要导入对应包:
from rest_framework import authenication
from rest_framework import permissions
NOTE:
由于是身份验证,因此我们首先得创建一个用户,Django中可通过如下命令创建一个管理员用户:
python manange.py createsuperuser
身份验证是将收到的请求和一组标识证书(如用户名密码、令牌)进行关联的一种机制,以便权限和策略可以根据这个标识证书来决定是否允许该请求。因此,身份验证发生在验证权限和限制检查之前。
当收到的请求通过身份验证时:
request.user
属性会设置为django.contrib.auth.User
对象,即我们登录的对象(我们定义用户继承于User)。request.auth
会设置为对应的Token
(如果带有Token)或者None
(如果不带有Token)。当收到请求身份验证失败时:
request.user
属性会设置为django.contrib.auth.models.AnonymousUser
对象。request.auth
会设置为None
。rest_framework.auth
中提供了以下四个身份验证方式:
使用HTTP、HTTPS的基本验证方式进行身份验证,即username/password验证方式,验证失败则返回HTTP 401 Unauthorized
响应。
使用Django的Session后台框架进行身份验证,验证失败则返回HTTP 403 Forbidden
响应。
基于Token的身份验证方式,客户端在请求时携带有一个Authorization
的请求头,和一个以”Token”开头的字符串,如:
Authorization: Token 401f7ac837da42b97f613d789819ff93537bee6a
如果验证失败,返回HTTP 401 Unauthorized
响应。
使用TokenAuthentication
时,需要使用Token
Model来创建一个数据表,做如下配置:
INSTALLED_APPS = (
...
'rest_framework.authtoken'
)
运行python manage.py makemigrations
和python manage.py migrate
之后会生成一张authtoken_token
的数据表,用来存放Token信息。
实际上,TokenAuthentication这种验证方式是每当创建一个用户,会生成对应的一个Token信息,并将该Token信息存放在数据表中。当收到请求时,将请求头中携带的Token和数据表中的Token进行验证,如果匹配则验证通过。因此,这种方式有两个缺点:
因此,在项目开发中经常使用另一个基于Token的验证方式——JSONWebToken,关于JWT相关内容会在之后的文章中进行总结。
远程用户验证,将身份验证委托给服务器进行,服务器中必须有REMOTE_USER
环境变量。
配置验证方式有两种方式:
配置全局默认验证方式对所有View都有效,在项目配置文件settings.py
中使用DEFAULT_AUTHENTICATION_CLASSES
:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
}
上述配置也是默认配置。
在GenericAPIView、ViewSets中通过authenication_class
配置:
from rest_framework import authentication
class Show(viewsets.ModelViewSet):
serializer_class = SnippetSerializer
queryset = Snippet.objects.all()
authentication_classes = (authentication.BasicAuthentication,)
由于Authenication仅仅是进行身份校验(根据request标记凭据),它并不能对接收的请求进行限制,如果需要对请求进行限制,还需要使用Permission进行限制。
权限检查通常使用request.user
和request.auth
属性中的身份验证信息来确定是否应允许传入请求。
当权限检查失败时,将根据以下规则返回HTTP 403 Forbidden
或HTTP 401 Unauthorized
:
HTTP 403 Forbidden
;WWW-Authenticate
请求头,则返回HTTP 403 Forbidden
;WWW-Authenticate
请求头,则返回HTTP 401 Unauthorized
。表示仅仅允许身份验证通过的用户访问,其他用户无法访问。
表示仅仅允许身份验证通过的用户访问,或者只允许只读请求(GET请求)访问。
表示仅仅允许管理员用户访问,普通用户无法访问。
其它权限不常用,就不一一整理,参考请见官方文档.
配置权限也有两种方式:
在settings.py
中,用DEFAULT_PERMISSION_CLASSES
配置:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
在GenericAPIView、ViewSets中使用permission_class
属性配置:
from rest_framework.permissions import IsAuthenticated
class Show(viewsets.ModelViewSet):
serializer_class = SnippetSerializer
queryset = Snippet.objects.all()
authentication_classes = (authentication.BasicAuthentication,)
permission_classes = (IsAuthenticated, )