12

I have a token string from Django REST Framework's TokenAuthentication.

I need to get the corresponding user object. How would I go about doing this?

Berry
  • 2,143
  • 4
  • 23
  • 46

5 Answers5

35
from rest_framework.authtoken.models import Token
user = Token.objects.get(key='token string').user
aliva
  • 5,450
  • 1
  • 33
  • 44
  • If you're getting `AttributeError: type object 'Token' has no attribute 'objects'` then add `"rest_framework.authtoken"` in **INSTALLED_APPS** section in your settings.py file. Source : https://github.com/encode/django-rest-framework/issues/6250#issuecomment-591192279 – Abhishek Iyengar Jan 01 '22 at 17:12
7

If you invoke the user object directly from the Token class, as presented in @aliva's solution, you will get a raw partial Django User with just the fields living in the database. If you need to get the real user object, with e.g. its computed properties, you can do this:

from rest_framework.authtoken.models import Token

user_id = Token.objects.get(key=request.auth.key).user_id
user = User.objects.get(id=user_id)
manuhortet
  • 479
  • 7
  • 20
3

Here is The default authorization token model:

@python_2_unicode_compatible
class Token(models.Model):
    """
    The default authorization token model.
    """
    key = models.CharField(_("Key"), max_length=40, primary_key=True)
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL, related_name='auth_token',
        on_delete=models.CASCADE, verbose_name=_("User")
    )
    created = models.DateTimeField(_("Created"), auto_now_add=True)

    class Meta:
        # Work around for a bug in Django:
        # https://code.djangoproject.com/ticket/19422
        #
        # Also see corresponding ticket:
        # https://github.com/encode/django-rest-framework/issues/705
        abstract = 'rest_framework.authtoken' not in settings.INSTALLED_APPS
        verbose_name = _("Token")
        verbose_name_plural = _("Tokens")

    def save(self, *args, **kwargs):
        if not self.key:
            self.key = self.generate_key()
        return super(Token, self).save(*args, **kwargs)

    def generate_key(self):
        return binascii.hexlify(os.urandom(20)).decode()

    def __str__(self):
        return self.key

As you can see this model has OneOnOne relations with the User model.

So if you want to get the User than mapped to specific Token:

from rest_framework.authtoken.models import Token

try:
    Token.objects.get(key="token").user
except Token.DoesNotExist:
    pass

For more information see Authentication documents

Phoenix
  • 3,996
  • 4
  • 29
  • 40
3

A better method to use would be to simply call request.user since access to the Token means an authenticated request. DjangoRestFramework gives access to request.auth and request.user on a successful TokenAuthentication.

Raghav Kukreti
  • 552
  • 5
  • 18
2

Suppose you wanna get userid and username when obtain auth token in Django Rest Framework

More info can get from https://www.django-rest-framework.org/api-guide/authentication/#by-exposing-an-api-endpoint

# in views.py
from rest_framework.auth.models import Token
from rest_framework.auth.views import ObtainToken
from rest_framework.response import Response

class MyObtainToken(ObtainToken):
   """Return User Info along with token"""
   def post(self, request, *arg, **kwarg)
       serializer = self.serializer_class(request.data, context={'request':request})
       serializer.is_valid(raise_exception=True)
       user = serializer.valided_data['user']
       token, _ = Token.objects.get_or_create(user)
       return Response(
            {
                 'token': token.key,
                 'username': user.username,
                 'userid': user.pk
            })
# in urls.py
urlpatterns += [path(r'api/obtain_auth_token', MyObtainToken.as_view()]
wllbll
  • 531
  • 5
  • 11