AllowAny
当前,任何匿名非授权用户都可以访问我们的 PostList 端点。 之所以知道这一点,是因为即使我们尚未登录,也可以看到我们的单个博客文章。 更糟糕的是,任何人都有权创建,编辑,更新或删除帖子!
在详细信息页面 http://127.0.0.1:8000/api/v1/1/
上,该信息也是可见的,任何随机用户都可以更新或删除现有博客文章。
之所以仍然可以看到“发布列表”终结点和“详细列表”终结点,是因为我们之前在 settings.py 文件中将项目的项目级别权限设置为 AllowAny。 简要提醒一下,它看起来像这样:
# blog_project/settings.py REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ] }
视图层权限
我们现在想要的是将 API 访问限制为经过身份验证的用户。 我们可以在多个地方执行此操作-项目级,视图级或对象级-但是由于目前我们只有两个视图,因此我们从那里开始,并为每个视图添加权限。
在您的 posts/views.py
文件中,从 Django REST 框架的顶部导入权限,然后向每个视图添加一个 permission_classes
字段。
# posts/views.py from rest_framework import generics, permissions # new from .models import Post from .serializers import PostSerializer class PostList(generics.ListCreateAPIView): permission_classes = (permissions.IsAuthenticated,) # new queryset = Post.objects.all() serializer_class = PostSerializer class PostDetail(generics.RetrieveUpdateDestroyAPIView): permission_classes = (permissions.IsAuthenticated,) # new queryset = Post.objects.all() serializer_class = PostSerializer
这就是我们所需要的。 通过 http://127.0.0.1:8000/api/v1/
刷新可浏览的 API。 看看发生了什么!
我们不再看到我们的“帖子列表”页面。 取而代之的是,由于我们尚未登录,因此会收到不友好的 HTTP 403 禁止状态代码。由于我们没有权限,因此可浏览的 API 中没有表格可以编辑数据。
因此,目前只有登录的用户可以查看我们的 API。 如果您使用超级用户或 testuser
帐户重新登录,则可以访问 API 端点。
但是,请考虑一下随着 API 复杂性的增长会发生什么。 将来我们可能会有更多的视图和终点。 如果我们要在整个 API 中设置相同的权限设置,则向每个视图添加专用的 permission_class
似乎是重复的。
最好只在项目级别更改一次权限,而不是对每个视图都进行一次更改,这会更好吗?
项目级别权限
此时,您应该点头。 在项目级别设置严格的权限策略并在视图级别根据需要放宽策略是一种更简单,更安全的方法。 这就是我们要做的。
幸运的是,Django REST Framework 随 附了许多我们可以使用的内置项目级权限设置,包括:
- AllowAny-任何经过身份验证的用户都具有完全访问权限
- IsAuthenticated-只有经过身份验证的注册用户才能访问
- IsAdminUser-只有管理员/超级用户有权访问
- IsAuthenticatedOrReadOnly-未经授权的用户可以查看任何页面,但只能查看经过身份验证的用户具有写,编辑或删除权限
要实施这四个设置中的任何一个,都需要更 DEFAULT_PERMISSION_CLASSES
设置和刷新我们的 Web 浏览器。 而已!
让我们切换到 IsAuthenticated
,这样只有经过身份验证或登录的用户才能查看 API。
更新 blog_project/settings.py
,如下:
# blog_project/settings.py REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # new ] }
现在返回到 views.py 文件,并删除我们刚刚进行的权限更改。
# posts/views.py from rest_framework import generics from .models import Post from .serializers import PostSerializer class PostList(generics.ListCreateAPIView): queryset = Post.objects.all() serializer_class = PostSerializer class PostDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Post.objects.all() serializer_class = PostSerializer
如果刷新“发布列表”和“详细列表” API 页面,您仍将看到相同的 403 状态代码。 现在,我们要求所有用户都必须先进行身份验证,然后才能访问 API,但是我们也始终可以根据需要进行其他视图级更改。