1
Context:

My project is using Django REST together with React.
I have made a User class that extends AbstractBaseUser, based on this tutorial to get a couple of extra fields, and to use email, instead of a username, to authenticate.
To log in, I'm using the djangorestframework-jwt to get an access token in React.

Problem:

I haven't found a way to get a user instance from Django REST based on the JSON Web Token.

What I have tried:

Tried using the JWTAuthentication with this view:

@api_view(['POST'])
@authentication_classes([JWTAuthentication])
def getUser(request, format=None):
    content = {
        'user': str(request.user),
        'auth': str(request.auth)
    }
    return Response(content)

It does kinda work since it returns the user's email address and token, but I want to get all user fields.

I also tried copying from this SO answer, but in setting.py I don't know how to specify the path to the JWTAuthentication class.

My user class:

from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError('The given email must be set')

        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password, **extra_fields):
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    date_joined = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True)
    about = models.CharField(max_length=250)

    objects = UserManager()

    USERNAME_FIELD = 'email'

    REQUIRED_FIELDS = [ 'first_name', 'last_name', 'password' ]

Hope someone can give some pointers. Thanks!

1 Answer 1

1

'user': str(request.user) this would fetch the user object and call __str__ method

@api_view(['GET'])
@authentication_classes([JWTAuthentication])
def GetUser(request, format=None):
    user = request.user
    content = {
        'id': user.id,
        'email': user.email,
        'first_name': user.first_name,
        # other_fields
        'auth': str(request.auth)
    }
    return Response(content)
Sign up to request clarification or add additional context in comments.

3 Comments

Now I'm getting 401 unauthorized on the backend. I tried adding @permission_classes([IsAuthenticatedOrReadOnly]) but no luck. I don't think I want any authentication other than having the token, is there an easy way around this?
401 unauthorized means you did not send the token with the request, so you need to generate the token first, take a look at these docs to understand how JWT works
I found my mistake, the access token lifetime was set to 5 minutes, and I haven't implementing refreshing yet, so I just set it to 1000 days for now. Thank you for the help!

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.