无法使用装饰器 [AllowAny] 访问 post 请求的 API 视图

Cannot access API view on post request using decorator [AllowAny]

我有一个简单的基于函数的 @api_view(['POST'])@permission_classes([AllowAny]) settings.py 中的 DRF 设置为:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}

documentation 说:

The AllowAny permission class will allow unrestricted access, regardless of if the request was authenticated or unauthenticated.

但是我在发出 post 请求时收到以下回复:

{
    "detail": "Authentication credentials were not provided."
}

可能是什么问题?我必须从设置中修改 DEFAULT_AUTHENTICATION_CLASSES 吗?我不希望在此 @api_view:

上发出请求时需要权限
@api_view(['POST'])
@permission_classes([AllowAny]) 
def reset_password_request(email):
    try:
    #...

accounts/urls.py:

urlpatterns = [
    path('user/<str:pk>/', views.getUserById, name='user'),
    path('user/password_reset_request/',
         views.resetPasswordRequest, name='password_reset_request'),
]

根据this,装饰器的位置是错误的。第一个被执行的装饰器应该在最上面。像这样将装饰器更改为底部:

@api_view(['POST'])
@permission_classes([AllowAny])
def reset_password_request(email):
    try:
    #...

查看 official documentation 以供参考。

让我们逐步完成它:添加 DEFAULT_PERMISSION_CLASSES 如下(用于故障排除):

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
     )
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}

** 编辑 1 **

尝试添加 rest_framework.authentication.SessionAuthentication 如下:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
     )
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication'
    ],
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}

** 编辑 2 **

现在您有了 403,将默认值修改为 rest_framework.permissions.AllowAny,如下所示。如果可行,请删除 DEFAULT_PERMISSION_CLASSES 并改用装饰器。

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
     )
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication'
    ],
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}

如果未指定DEFAULT_PERMISSION_CLASSES,则默认允许无限制访问。

问题出在您的 URL 模式中,其中 password_reset_request 满足 <str:pk> 并且 getUserById@permission_classes([...]) 被调用。

要么使用uuid路径转换器:

urlpatterns = [
    # path('user/<str:pk>/', views.getUserById, name='user'),  # Change this
    path('user/<uuid:pk>/', views.getUserById, name='user'),   # to this
    path('user/password_reset_request/',
         views.resetPasswordRequest, name='password_reset_request'),
]

或重新排序以首先匹配 password_reset_request

urlpatterns = [
    # path('user/<str:pk>/', views.getUserById, name='user'),  # Move this
    path('user/password_reset_request/',
         views.resetPasswordRequest, name='password_reset_request'),
    path('user/<str:pk>/', views.getUserById, name='user'),    # to here
]

参考文献: