1

I am doing a project with REST API and Django Rest Framework. I currently have an issue in my post request where some of my endpoints return HTTP 401 Unauthorized, though all other get or update objects are returning correct responses. I am using -> djangorestframework-simplejwt==5.2.2.

settings.py

INSTALLED_APPS = [
    # ...
    'rest_framework_simplejwt.token_blacklist',
    # ...

]

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

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=50),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',

    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    "JSON_ENCODER": None,
    'JWK_URL': None,
    'LEEWAY': 0,
    
    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
    'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

main urls.py

schema_view = get_schema_view(
  openapi.Info(
    title="Blog Backend API's",
    default_version="v1",
    description="This is the documentation for the backend API",
    terms_of_service="http://mywebsite.com/policies/",
    contact=openapi.Contact(email="[email protected]"),
    license=openapi.License(name="BDSM License"),
  ),
  public=True,
  permission_classes=(permissions.AllowAny, )
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path("api/v1/", include("api.urls")),

    path("", schema_view.with_ui('swagger', cache_timeout=0), name="schema-swagger-ui"),
]

views.py

class PostCommentApiView(APIView):
  @swagger_auto_schema(
    request_body=openapi.Schema(
      type=openapi.TYPE_OBJECT,
      properties={
          'post_id': openapi.Schema(type=openapi.TYPE_INTEGER),
          'name': openapi.Schema(type=openapi.TYPE_STRING),
          'email': openapi.Schema(type=openapi.TYPE_STRING),
          'comment': openapi.Schema(type=openapi.TYPE_STRING),
      },
    ),
  )

  def post(self, request):
    post_id = request.data["post_id"]
    name = request.data["name"]
    email = request.data["email"]
    comment = request.data["comment"]

    post = api_models.Post.objects.get(id=post_id)

    api_models.Comment.objects.create(
      post=post,
      name=name,
      email=email,
      comment=comment,
    )

    api_models.Notification.objects.create(
        user=post.user,
        post=post,
        type="Comment"
      )
    
    return Response({"message": "Comment Sent"}, status=status.HTTP_201_CREATED)

api/ urls.py

urlpatterns = [
    path("post/comment-post/", api_views.PostCommentApiView.as_view()),
]

I am getting this as a response

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

and in my terminal i am getting "Unauthorized: /api/v1/post/comment-post/". How can i solve this post request issue. I want to make a big project but i'm stuck on all of the post requests.

2 Answers 2

1

If you look at settings.py

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

The default permission class is specified as IsAuthenticated and the default authentication class is specified as JWTAauthentication.

That's why only users who are authenticated and authenticated will be allowed for all requests.

The 401 error you encountered was also set to JWTAuthentication as the default authentication class, which is an error that occurs when a client makes a request without setting a header related to authentication.

Authorization: Bearer {access_token}

If your PostCommentAPIVIew is a class that requires authentication and authorization, the client must pass it in the request header in the form of "Bearer {access_token}" as the value of the Authorization key.

However, if PostCommentAPIView is the logic allowed for all users, settings.py DefaultPermission, DefaultAuthentication should be removed or the value should be overridden.

class PostCommentApiView(APIView):
  authentication_classes = []
  permission_classes = []

  @swagger_auto_schema(
      ...
  )

  def post(self, request):
      ...
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot brother. I just edited the PostCommentApiView like you suggested. It is working fine now. You saved lot of my time 👏
0

HTTP error code 401 is different from error code 403. The former is for authentication, while the latter is for authorization. Essentially, authentication must first happen before authorization. Therefore, if you are getting code 401, it means the user could not be identified from the simplejwt token, or the token is invalid or expired.

Authentication credentials were not provided is the error given if you do not have the authorization headers. Remember these messages can be overriden as well.

However, be careful when overriding permission_classes and authentication_classes for an APIView with post method. For Get, that can be understood. But for write methods such as POST, PUT, PATCH or DELETE, it is a vulnerability you should avoid.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.