Multiple Authentication Tokens per User with Django REST Framework

In this post I will show you how to set up token authentication with Django REST Framework (or short DRF), with the special twist that each user can have multiple different tokens at the same time. This is not possible with DRF out of the box and needs some custom code.

But why would you even want multiple tokens per user? Because you really want to use a different token for each client. If every client uses the same token, the token is basically a password. If you want to change the token in one client, you have to change it in every client.

Enough reasoning, let’s write some code. If you look at the definition of the Token model that comes with DRF, you might notice that it has a severe limitation: it has a One-to-One relationship to the user model, so each user can only have one token.

Luckily, it is quite easy to use a custom token model. First, you have to remove rest_framework.authtoken from your INSTALLED_APPS. Then create your own token model as a subclass of DRF’s Token:

Our custom model is hiding some fields inherited from the superclass. Field hiding works only for abstract models, but the Token class is abstract
as long as the rest_framework.authtoken app is not installed. You did remove it from your INSTALLED_APPS, right?

Note that hiding of fields from abstract models is a new feature in Django 1.10. In older versions of Django, field hiding is not permitted. If you are not using Django 1.10 yet, the easiest workaround is probably to just copy the required code from DRF.

You can put our Token model in an existing app or create a new one for it. If you decide to do the latter, don’t forget to add it to INSTALLED_APPS!

How is the new Token model different?

The OneToOne relationship to user model has been replaced with a ForeignKey, allowing multiple tokens per user

The key is indexed and unique, but no longer a primary key. That means Django will create a numeric primary key by default. Why does that make sense? If you have multiple tokens, you might want to have a way to manage them. That usually means referring to tokens by a URL. As the key is supposed to be secret, it should not appear in URLs, because URLs usually end up in a kind of places, e.g. server logs.

Tokens now have a name to be able to differentiate them. The name should be unique per user

Now you have to tell DRF to use our custom token class. For that, simply create a subclass of TokenAuthentication and override the model attribute. You can put that class in any module you want, I prefer creating a file called authentication.py in the same app as the token model.

Summary

So what did we do today?

We created a custom Token model with a ForeignKey to User instead of a OneToOneField

We created a custom authentication class that uses our Token

What’s next? If your site is already online and has tokens that are in use, you might want to create a data migration to keep your users happy. You also need some kind of management interface to manage the tokens. This could be handled in the admin or as part of some kind of account settings page. For now, both is left as an exercise to the reader.

Thanks I tried copying and wasnt successful. I also tried to upgrade to 1.11 with more success. However it seems I still have to rewerite the TokenAuthentication class to be able to support multiple tokens per user and take into account the name field. I use djoser project to expose REST Apis for registration/login etc. Thanks