AllowAny CreateAPIView 为未经身份验证的用户返回 401

时间:2021-06-30 09:27:17

标签: django django-rest-framework jwt django-rest-framework-simplejwt

我将 DRF 与 djangorestframework-simplejwt 包一起使用。在我的 settings.py 中:

INSTALLED_APPS = [
    ...
    'rest_framework',
    ...
]

...

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTTokenUserAuthentication',
    ),
}

SWAGGER_SETTINGS = {
   'SECURITY_DEFINITIONS': {
      'Bearer': {
            'type': 'apiKey',
            'name': 'Authorization',
            'in': 'header',
            'description': 'E.g. \'Bearer jwt.token.here\''
      }
   }
}

在我的应用程序的views.py中:


...

class PublicCreateView(generics.CreateAPIView):
    """
    Should be available for unauthenticated users
    """
    serializer_class = PublicThingSerializer

    def post(self, request, *args, **kwargs):
        return Response("It works!", 200)
...

但出于某种原因,此视图会为未经身份验证的用户返回 401 响应。我尝试了很多方法,我得到的最好结果是注意到当我从 REST_FRAMEWORK 中完全删除 settings.py 配置时,响应代码更改为 403 forbidden。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

正如 MojixCoder 在评论中提到的那样,清理 cookie 可能已经解决了这个问题,但是这一次,经过几个小时的调试后发现我的问题实际上与{有关{1}} 声明(简化):

urls.py

问题是,当将请求路由到 url from . import views urlpatterns = [ path("something/", views.SomethingViewSet()), ... path("something/more/", views.PublicCreateView.as_view()) ] 时,Django 实际上使用了第一个匹配规则(完全可以理解和预期的行为),它在 /something/more/ 中设置了 rest_framework.permissions.IsAuthenticated。此行为在 Django 文档中关于 URL 调度程序的 How Django processes a request 部分下的第 3 点中进行了描述:

<块引用>
  1. Django 按顺序遍历每个 URL 模式,并在第一个匹配请求的 URL 的位置处停止,并与 path_info 匹配。

希望它可以节省某人的时间。由于 API 只返回了一个通用的 permission_classes 答案,令人惊讶地难以弄清楚。

答案 1 :(得分:0)

from rest_framework.permissions import AllowAny
 class PublicCreateView(generics.CreateAPIView):
  permission_classes = (AllowAny,)
  serializer_class = PublicThingSerializer

  def post(self, request, *args, **kwargs):
    return Response("It works!", 200)