Faisal Nazik
Faisal Nazik

Reputation: 2873

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

I have a simple function-based @api_view(['POST']) with @permission_classes([AllowAny]) and DRF settings in settings.py are:

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

The documentation says:

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

But I'm getting the following response on making a post request:

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

What might be the problem? Do I have to modify DEFAULT_AUTHENTICATION_CLASSES from the settings? I don't want the permissions to be required while making the request on this @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'),
]

Upvotes: 1

Views: 2268

Answers (3)

aaron
aaron

Reputation: 43103

If DEFAULT_PERMISSION_CLASSES is not specified, it defaults to allowing unrestricted access.

The problem is in your URL patterns, where password_reset_request satisfies <str:pk> and getUserById with @permission_classes([...]) is called instead.

Either use the uuid path converter:

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'),
]

Or reorder to match password_reset_request first:

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
]

References:

Upvotes: 2

sitWolf
sitWolf

Reputation: 1011

Let's work through it step by step: Add DEFAULT_PERMISSION_CLASSES as follows (for troubleshooting):

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',
}

** EDIT 1 **

Try adding rest_framework.authentication.SessionAuthentication as follows:

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',
}

** EDIT 2 **

Now that you have a 403, modify the default to rest_framework.permissions.AllowAny as shown below. If this works, remove the DEFAULT_PERMISSION_CLASSES and use decorators instead.

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',
}

Upvotes: 0

Siva Sankar
Siva Sankar

Reputation: 1830

According to this, the position of decorator is wrong. The first decorator to be executed should be on the top. Change your decorator to the bottom like this:

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

Check out the official documentation for reference.

Upvotes: 0

Related Questions