Luishi
Luishi

Reputation: 1

User not found for token auth in django rest framework

Perfoming a rest api crud in django rest framework, i have implemented JWT authentication with djangorestframework_simplejwt. And i stock managing those authetications, first, i logged an user using authenticate to validate credentials, if credentials are valid, return the user data and the generated token for it, then i put this token in the Authorization header like this: Authorization Bearer token (i'm using thunder client in vs code) but it raise the following response without any exceptions:

{
  "detail": "User not found",
  "code": "user_not_found"
}

This response raise when i go to a protected view. The token it's supose to be invalid or expired but don't know why, i make some console prints but the code doesn't run because of this

I'm new handle this type of authentications and i don't know what i'm doing wrong, any kind of help would be appreciated.

Here's my UserLogin view:

class UserLogin(APIView):
    permission_classes = [AllowAny]
    def post(self, request, *args, **kwargs):
        username = request.data.get("username")
        password = request.data.get("password")
        user = authenticate(request, username=username, password=password)
        if user is not None:
            serializer = UserSerializer(user)
            refresh = RefreshToken.for_user(user)
            access = str(refresh.access_token)
            return JsonResponse({'access': access, 'user': serializer.data}, status=status.HTTP_200_OK)
        return JsonResponse({'Detail': 'Invalid Credentials'}, status=status.HTTP_401_UNAUTHORIZED)

(Here i validate an user and generate a token for it, this view works and return me the user data and his auth token)

I have defined a custom middleware which runs even if the authentication fails, it returns the token set in the authorization header but the user returns None:

class JWTMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        token = request.META.get('HTTP_AUTHORIZATION', '').replace('Bearer', '').strip()
        print(token)
        if token:
            try:
                decoded_token = AccessToken(token)
                user = decoded_token.payload.get('mongo_id')
                request.user = user
                print(user)
            except (InvalidToken, KeyError):
                print('Invalid token')

        response = self.get_response(request)

        return response

Note: mongo_id is an ObjectIdField defined as the primary key of my user model (Yes, i'm using mongodb as my database using djongo library in my project)

And here's the settings added in settings.py for djangorestframework_simplejwt tokens:

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

SIMPLE_JWT = {
    'USER_ID_FIELD': 'mongo_id',
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1)
}

In conclusion, the error is maybe because the token is invalid or expired, but i don't know what could be causing it.

If you need more info please let me know. Thanks for advice

Upvotes: 0

Views: 1971

Answers (4)

amirreza farokhy
amirreza farokhy

Reputation: 9

Your code is't good for test api like JWT. Please install and try with Postman and set Bear token. here is a link: https://www.postman.com/

Upvotes: -1

Beckham Dennis
Beckham Dennis

Reputation: 11

I faced a similar problem and I solved it by setting the AUTH_USER_MODEL attribute in the settings.py file. If you are using a custom user without inheriting any of the already-defined user models then the is_anonymous field must be included in the model definitions. Also, you can use the get_user_model function from Django to access the model to verify if it is pointing to your user model.

Upvotes: 1

Dhia Eddine Benterki
Dhia Eddine Benterki

Reputation: 11

Another reason this might be happening is , The token is Still valid not expired and not blacklisted , but the user associated with it was somehow deleted and the user in the React application was not logedout so he is still hitting the protected endpoints leading to the backend to decode the jwt containing the user_id and finding out that the user is nowhere to be found Thus returning the 404 Not Found

Upvotes: 0

McConnell
McConnell

Reputation: 256

I had encountered the same issue. In my case, I had set 'USER_ID_FIELD': 'username', but the 'username' field was not mandatory in my project. As a result, users who had not set the 'username' field would always encounter the 'user not found' error.

Make sure that the 'mongo_id' field is spelled correctly and that it exists for all users.

Upvotes: 0

Related Questions