认证和权限控制是web开发中较为重要的知识点,我们看下django rest_framework的认证和权限是如何实现的
我们知道,在django中,提供内置的认证与权限方式,通过维护几张数据库表(如auth_user、auth_group、auth_permission等),并提供封装好的方法(如:authenticate()、login()、logout())实现认证与权限。
在rest_framework的APIView基础类中,对认证与权限做了更高级的封装,如下:
class APIView(View):
# The following policies may be set at either globally, or per-view.
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
authentication_classes 为认证属性,默认会读取settings.py中的DEFAULT_AUTHENTICATION_CLASSES
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
}
permission_classes 为权限属性,默认会读取settings.py中的DEFAULT_PERMISSION_CLASSES
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
当然,也可以在类里指定认证与权限方法,如下:
from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication, BasicAuthentication, SessionAuthentication
from rest_framework.permissions import IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly, AllowAny
class TestView(APIView):
authentication_classes = (BasicAuthentication, )
permission_classes = [IsAuthenticated]
def get(self, request):
print("++++++++++++++++", request.user)
print(request.auth)
return Response({"data": "hahah"})
当请求认证成功后,DRF会在请求对象request中设置request.user和request.auth属性,一般request.user为django用户实例,request.auth为None或认证附带的值(如token认证的token值),当认证失败后DRF会默认设置request.user为django.contrib.auth.models.AnonymousUser实例,request.auth默认设置为None。
DRF提供如下几种常见认证方式:
1、BasicAuthentication,基于用户名密码认证方式
2、SessionAuthentication,基于Session认证方式
3、TokenAuthentication,基于令牌认证方式(一个用户绑定一个令牌,每次请求在请求头中加上
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
)
DRF提供如下几种常见权限:
IsAuthenticated, 认证通过
IsAdminUser, 管理员权限
IsAuthenticatedOrReadOnly,
AllowAny,无需认证(默认)
DRF的认证与权限结合较为紧密,只有认证没有权限控制的话是不生效的,如只设置authentication_classes 不设置permission_classes , 这点切记!
另外,认证与权限都可以自定义实现,分别继承BaseAuthentication基础认证类、BasePermission基础权限类,这样就可达到自己想要的任何权限控制了。
附上链接:
https://www.django-rest-framework.org/api-guide/authentication/
https://www.django-rest-framework.org/api-guide/permissions/