新建一个自定义类,该类继承rest_framework.authentication中的BaseAuthentication
类,重写其中的authenticate
方法。将需要的认证逻辑写在里面。当认证通过是需要返回两个值,其中一个值最终给了Request
的user
。认证失败时,抛出异常:APIException
或者AuthenticationFailed
。其中该方法必须重写,如不重写其中没有认证逻辑,则直接抛出异常。
为方便管理,认证类写在新建的.py文件中。
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01 import models # 自定义模型
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
# 从META中取出请求中带的登录接口返回给前端的token
token = request.META.get('HTTP_TOKEN')
if token:
user_token = models.Token.objects.filter(Token=token).first()
if user_token:
return user_token.user, token
else:
raise AuthenticationFailed('认证失败')
else:
raise AuthenticationFailed('需要认证')
REST_FRAMEWORK
中添加DEFAULT_AUTHENTICATION_CLASSES
。如下所示:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.user_auth.MyAuthentication",] #可以有多个
}
authentication_classes
。如下所示:
class BookAPIView(ModelViewSet):
authentication_classes = [MyAuthentication, ]
'''
可以是元组也可以是列表,里面可以有多个值,当有多个值的时候,从左到右依次认证。其中第一个认证不能有两个返回值,否则只能进行第一个认证。有多个认证时,需要将返回值为两个的放到最后
'''
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
authentication_classes
设置为空。如下所示:
class LoginView(APIView): authentication_classes = () def post(self, request): ...
新建一个类,继承rest_framework.permissions中的BasePermission,并重写其中的has_permission方法,其中是验证权限的逻辑。如果验证通过则return True,如果验证失败则返回False。
示例:
from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
def has_permission(self, request, view):
'''
在进行权限验证之前,drf会首先对请求进行认证操作,当其认证通过时之后才会进行权限认证。此时request中已经包含了登录用户的信息,我们可以将其取出进行权限验证。
'''
user=request.user # 当前登录用户
if user.user_type==1:
return True
else:
return False
同认证类相似,权限类也有全局使用,局部使用和局部禁用。
其中全局使用的配置是:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",],
'DEFAULT_PERMISSION_CLASSES': [
'app01.app_auth.UserPermission',
],
}
局部使用则是在相应的视图类中添加 permission_classes 属性。比如:
class TestView(APIView):
permission_classes = [app_auth.UserPermission,]
pass
将视图类中的permission_classes 设置为空即可在全局配置了权限的情况下实现,权限的局部禁用。
drf为我们内置了几个权限类,当我们的的需求类似时,可以直接使用其内置的权限类,避免代码冗余。这几个权限类依次是
IsAdminUser
校验Django自带用户表中的is_staff字段,判断认证用户是否是管理员(注意:其判断的不是is_superuser字段,而是is_staff,即该用户是职员状态是就可以通过权限认证)。IsAuthenticated
所有通过认证的请求都可以通过权限验证,都会返回True。IsAuthenticatedOrReadOnly
当请求通过认证或者请求是'GET
', 'HEAD
', 'OPTIONS
'方式时,可以通过权限验证。AllowAny
所有请求都可以通过权限校验,当你没有配置权限类的时候就会默认使用AllowAny 。权限的校验依靠于认证类返回的结果,所以我们使用时必须要搭配相应的认证类使用。
新建一个频率类。继承rest_framework.throttling中的SimpleRateThrottle,重写get_cache_key 方法。其中可以取出请求中的ip,user,设备信息等,将选用的频率限制标准返回即可。即返回ip即按照ip限制访问频率,返回用户名或用户对象即根据用户进行限制。
示例:
from rest_framework.throttling import SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):
scope='ip'
'''
其中scope属性为配置中访问频率设置的关键字,必须在频率类中对该属性进行赋值,且与sttings中要一一对应。
'''
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR')
throttle_classes
属性即可。示例:
class TestView(APIView): throttle_classes = [MyThrottle,] pass
throttle_classes
设置为空即可在全局配置了频率限制的情况下实现,频率限制的局部禁用。
drf为我们内置了几个权限类,依次为:
UserRateThrottle
:对登录用户进行频率限制。如果登录用户经过了认证,则限制的依据是该用户的user_id,否则就是该请求的ip地址。setting中的scope为user
。AnonRateThrottle
:对未登录用户进行频率限制,限制依据是用户请求中的ip地址,setting中的scope为anon
。pip3 install django-filter
示例:
# 视图
from rest_framework.filters import OrderingFilter
class BooksView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [OrderingFilter]
ordering_fields = ('id', 'price')
# urls.py
path('books/', views.BooksView.as_view()),
# 使用
http://127.0.0.1:8000/books/?ordering=-price
http://127.0.0.1:8000/books/?ordering=price
http://127.0.0.1:8000/books/?ordering=-id