pythondjangodjango-rest-frameworkdjango-rest-framework-simplejwtdjango-rest-framework-jwt

Unauthorized response to POST request in Django Rest Framework with Simple JWT


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="sabab@gmail.com"),
    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.


Solution

  • 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):
          ...