对于未经身份验证的用户,AllowAny CreateAPIView 返回 401

Lis*_*Lis 1 django jwt django-rest-framework 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\''
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

在我的应用程序的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)
...
Run Code Online (Sandbox Code Playgroud)

然而由于某种原因,此视图返回401未经身份验证的用户的响应。我尝试了很多事情,我得到的最好的结果是注意到当我完全删除配置时REST_FRAMEWORKsettings.py响应代码更改为403 forbidden. 有任何想法吗?

Lis*_*Lis 5

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

from . import views

urlpatterns = [
    path("something/", views.SomethingViewSet()),

    ...

    path("something/more/", views.PublicCreateView.as_view())
]
Run Code Online (Sandbox Code Playgroud)

问题是,当将请求路由到 url 时,/something/more/Django 实际上使用了rest_framework.permissions.IsAuthenticatedpermission_classes. 此行为在 Django 文档中有关 URL 调度程序的“Django 如何处理请求”部分的第 3 点中进行了描述:

  1. Django 按顺序运行每个 URL 模式,并在第一个与所请求的 URL 匹配的 URL 模式处停止,与 path_info 匹配。

希望它可以节省某人的时间。由于 API 仅返回一个通用401答案,因此很难弄清楚。