Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django JWT Get User Info

I'm using Django JWT authentication with the Django Rest Framework.
How can I get user info of the logged in user after I retrieve the token?

like image 905
cclloyd Avatar asked May 18 '18 06:05

cclloyd


3 Answers

just check your app settings file, whether you have specified the jwt authentication backend or not. if it mentioned there and if you are using User model ( in otherwords django.contrib.auth.models.User) request.user will work

If you are using your own custom User model

from django.conf import settings
from rest_framework import authentication
from rest_framework import exceptions
from rest_framework.authentication import get_authorization_header
import CustomUser # just import your model here
import jwt

class JWTAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request): # it will return user object
        try:
            token = get_authorization_header(request).decode('utf-8')
            if token is None or token == "null" or token.strip() == "":
                raise exceptions.AuthenticationFailed('Authorization Header or Token is missing on Request Headers')
            print(token)
            decoded = jwt.decode(token, settings.SECRET_KEY)
            username = decoded['username']
            user_obj = CustomUser.objects.get(username=username)
        except jwt.ExpiredSignature :
            raise exceptions.AuthenticationFailed('Token Expired, Please Login')
        except jwt.DecodeError :
            raise exceptions.AuthenticationFailed('Token Modified by thirdparty')
        except jwt.InvalidTokenError:
            raise exceptions.AuthenticationFailed('Invalid Token')
        except Exception as e:
            raise exceptions.AuthenticationFailed(e)
        return (user_obj, None)

    def get_user(self, userid):
        try:
            return CustomUser.objects.get(pk=userid)
        except Exception as e:
            return None

and add the following settings in your app

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'path_to_custom_authentication_backend',
        ....
    )
}

now in each view/viewset you can access the user object with request.user

like image 69
Asif Mohammed Avatar answered Oct 17 '22 04:10

Asif Mohammed


By reading the documentation on DRF Authentication and as @neverwalkaloner mentions in his comment, we see that we can access the logged-in user's django.contrib.auth.User instance in a view, by using the request.user attribute.

Reading the documentations of both the recommended JWT modules for DRF:

  • https://github.com/GetBlimp/django-rest-framework-jwt
  • https://github.com/davesque/django-rest-framework-simplejwt

I didn't find any evidence that they change/override the method of accesing the logged in user's instance info.

like image 3
John Moutafis Avatar answered Oct 17 '22 04:10

John Moutafis


If you are familiar with django rest jwt, you may see a config like this in your settings.py:

JWT_AUTH = {
 .....
'JWT_RESPONSE_PAYLOAD_HANDLER':
    'rest_framework_jwt.utils.jwt_response_payload_handler',

'JWT_SECRET_KEY': SECRET_KEY,
....
}

You can simply create a method for example my_custom_jwt_response_payload_handler like below and address JWT_RESPONSE_PAYLOAD_HANDLER to new handler:

def jwt_response_payload_handler(token, user=None, request=None):

return {
    'token': token,
    'user': {
        'username': user.username, 'id': user.id,
        ...
    }
}

You can add any data that you want in this response. then patch settings.py with your new handler:

JWT_AUTH = {
 .....
'JWT_RESPONSE_PAYLOAD_HANDLER':
    'localtion-to-my-own-handler-file.my_custom_jwt_response_payload_handler',
....
}

For better understanding i suggest read original source and comments for jwt_response_payload_handler in here

like image 3
Reza Torkaman Ahmadi Avatar answered Oct 17 '22 05:10

Reza Torkaman Ahmadi