Issue with Database Queries in Authenticated Django API Calls Despite JWT Verification

103 views Asked by At

Each time an authorized API call is made using a bearer token (specifically a simple JWT), a database query is executed to retrieve user details, even though JWT Authentication is supposed to eliminate the need for database validation. Could someone help me understand the reason behind these database queries and suggest a solution to avoid them while still ensuring proper authentication through JWT? Your insights would be greatly appreciated!

When making a request to a Django API with a JWT bearer token, an extra database call is initiated to retrieve user details associated with the user ID specified in the token payload.

SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", 
       "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", 
       "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined"
FROM "auth_user"
WHERE "auth_user"."id" = 2
LIMIT 21;
args=(2,); alias=default

The execution of this database query is unexpected, and I am unsure about the reason for its occurrence. Can anyone assist me in determining the cause of this DB Query?

The sample API view I tried is below: class TestView(ViewSet): permission_classes = (IsAuthenticated,) def list(self, request): return Response({'Key': 'Test '})

I didn't include any user details in the API view. However, I've noticed that the database query for user information is being generated in all API calls.

In anticipation, I appreciate your assistance.

1

There are 1 answers

5
Nico Griffioen On

A JWT token is a string of three base64 encoded strings seperated by a .

These three parts are:

  • header
  • payload
  • signature

The header contains information about the type of token and the signing algorithm used.

The signature is used to verify that the token has not been tampered with.

The payload is the actual message of the JWT. It is a JSON object containing a set of 'claims'.

An example from the JWT standard of a claims set:

{"iss":"joe",
 "exp":1300819380,
 "http://example.com/is_root":true}

The JWT standard provides some default recommended claims, and there are also public claims. Although some are recommended, none of these claims are mandatory. A JWT payload could therefore contain anything.

So there is no guarantee that all (or any) user information is available in a JWT. Depending on the implementation of JWT authentication, an application (e.g. Django) might still need to do a database query to get the user's actual information.

I would need to know the specifics of your project, but in most cases Django's AuthenticationMiddleware (Or similar middlewares), will always perform a database lookup when request.user is called.

If you do have all you information available in your JWT, you could write a custom middleware to handle authentication/authorization without using request.user.

More info on the JWT specification can be found in the JWT specification.