Token Authentication seems to be an Authentication Scheme that gives people the most trouble. The reason appears to be a misunderstanding not of so much how to implement it, but how to actually use it.

For example, the Django REST Framework documentation says that for every request, you have to add an Authorization Header to your requests. But, how do you create that Authorization header?

Also…

How do I use Token Authentication to authorize external clients? These are serious questions that I’ve seen from people just like you. But, the difference is that after reading this post, you’ll understand how that works. I’ll show you how to implement Token Authentication using Django REST Framework. Then, I’ll give you a sample application that uses Token Authentication to authenticate users within a Django Application. Best of all, you can take what you learn from my sample code to use in external clients (Javascript clients) to authenticate / authorize users with your RESTful API.

Want to get started learning Django REST Framework? Sign up for a FREE 7 Day Email Course today. Click here for more information

WARNING: NEVER, EVER use Token Authentication without using Secure HTTP (HTTPS). If you want to run my sample code or play around with your own code locally it is OKAY to use Unsecure HTTP (HTTP). However, NEVER do it in production. You’ve been warned.

Introduction to Token Authentication

Token Authentication is a way to authorize users by using an API Key or Auth Token. The way Django REST Framework implements Token Authentication requires you to add a header for each request. This header will be in the following format:

1 Authorization: Token 93138ba960dfb4ef2eef6b907718ae04400f606a

Authorization is the header key and Token 93138ba960dfb4ef2eef6b907718ae04400f606a is the header value. Note, there is a space between Token and the token itself.

The server where your API lives will read off the user’s token and determine if there is a user assigned to that particular token.

This is Token Authentication in a nutshell. It really doesn’t get anymore complicated than that. The difficulty is implementing it for each of the clients that will use the API (Javascript apps, Desktop apps, Commandline, etc.)

How to Implement Token Authentication

The implementation is a bit more complicated than other Authentication Schemes so take this slow, digest each piece of the puzzle and make sure to download my sample code so you can see what I’m doing each step of the way.

Preliminary Configuration

As with all Django REST Framework Authentication schemes, you must configure the authentication scheme that you will use in your settings.py file.

myproject/settings.py

1 2 3 4 5 6 7 8 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES' : ( 'rest_framework.authentication.TokenAuthentication' , ), 'DEFAULT_PERMISSION_CLASSES' : ( 'rest_framework.permissions.IsAuthenticated' , ) }

This is where it’s a little different than other Authentication schemes. You will also need to add an app to your INSTALLED_APPS array. The reason for this is because Token Authentication requires a special model called Token which is used to store your user authentication tokens.

In my sample application, my INSTALLED_APPS tuple looks like this:

myproject/settings.py

1 2 3 4 5 6 7 8 9 10 11 12 INSTALLED_APPS = ( 'django.contrib.admin' , 'django.contrib.auth' , 'django.contrib.contenttypes' , 'django.contrib.sessions' , 'django.contrib.messages' , 'django.contrib.staticfiles' , 'polls' , 'accounts' , 'rest_framework' , 'rest_framework.authtoken' , )

Now, in order to install the app and update the database with the new Token model, it is imperative that we run python manage.py migrate .

Now, you should be ready to create tokens for your users, create a post_save method on your User model so that whenever a new user is added to your database it will automatically create a token for them.

Create Tokens for your Users

Go to your project shell by typing this command at a terminal: python manage.py shell . You should be presented with a prompt that looks like this: >>> .

Now, you’re going to type in the following code:

1 2 3 4 5 6 7 from django.contrib.auth.models import User from rest_framework.authtoken.models import Token users = User . objects . all () for user in users: token, created = Token . objects . get_or_create(user = user) print user . username, token . key

This code will retrieve all the users that currently exist in your database. It loops through each of them, generates a unique token for each of them and prints our their username and their token. It’s nice to print out their username and the token so you can see that it in fact worked correctly.

Now, you don’t want to manually create tokens for your users whenever a new user registers for your web app so you’ll have to create a special function that will automatically create a token for each new user:

myproject/accounts/models.py

1 2 3 4 5 6 7 8 9 from django.conf import settings from django.db.models.signals import post_save from django.dispatch import receiver from rest_framework.authtoken.models import Token @receiver (post_save, sender = settings . AUTH_USER_MODEL) def create_auth_token (sender, instance = None, created = False, ** kwargs): if created: Token . objects . create(user = instance)

Now, every time a new user is saved in your database, this function will run and a new Token will be created for that user.

Create a Route for Retrieving a Token for Successfully logged in users

Django REST Framework provides a view that simply returns the user’s token when they provide a correct username / password combo.

Let’s add this now:

myproject/accounts/urls.py

1 2 3 4 5 6 7 8 9 10 11 12 13 14 from django.conf.urls import url from django.conf import settings from django.conf.urls.static import static from . import views as local_view from rest_framework.authtoken import views as rest_framework_views urlpatterns = [ # Session Login url( r '^login/$' , local_views . get_auth_token, name = 'login' ), url( r '^logout/$' , local_views . logout_user, name = 'logout' ), url( r '^auth/$' , local_views . login_form, name = 'login_form' ), url( r '^get_auth_token/$' , rest_framework_views . obtain_auth_token, name = 'get_auth_token' ), ] + static(settings . STATIC_URL, document_root = settings . STATIC_ROOT)

The bottom route is what you should notice:

1 url( r '^get_auth_token/$' , rest_framework_views . obtain_auth_token, name = 'get_auth_token' ),

Now, when POST’ing to http://localhost:8000/accounts/get_auth_token/ with the following data (assuming this username / password exists): { 'username': 'admin', 'password': 'admin' } you’ll receive something that looks like the following: { 'token': '93138ba960dfb4ef2eef6b907718ae04400f606a' }

You’re done implementing Token Authentication. So, what can you do with this Authentication Scheme? Whatever you want. Let’s look at some sample code to see how this works.

I’m launching my e-book very shortly (March 10, 2017). To get additional information, click here.

Click Here to Download the Sample Code

How to use the Sample Code

Unzip the code repository Change directory to the unzipped code repository Run the command python manage.py runserver Go to http://localhost:8000/polls/ to run the code. You’ll be redirected to a very crude login form Type admin for the username and admin for the password You’ll be redirected to the polls app and application should work. Go to http://localhost:8000/accounts/logout to invalidate the cookie that holds the Authentication Token. Download Postman from https://www.getpostman.com/ Open Postman. Make sure the dropdown says, “GET”. Type in: http://localhost:8000/polls/api/questions/1 into the address bar. Make sure under Authorization “No Auth” is selected. Under “Headers” add the Header key: Content-Type. Make the Header value: application/json Click “Send” and you should retrieve "Authentication credentials were not provided." Now, under “Headers” underneath “Content-Type” add the Header key: Authorization and add the Header value: “Token 93138ba960dfb4ef2eef6b907718ae04400f606a” (without the quotes). Click “Send” again and you should be getting the correct data.

Homework (If you’d like…)

Look at ALL of my sample code. Underneath the admin form in login.html there is some Javascript that creates a call to http://localhost:8000/accounts/get_auth_token/ with my username and password. When I retrieve the token, I put it into a cookie called “token” and I redirect to the ‘/polls/‘ app.

there is some Javascript that creates a call to with my username and password. When I retrieve the token, I put it into a cookie called “token” and I redirect to the ‘/polls/‘ app. In the app.js file (where my AngularJS code lives), I created an “Interceptor”. The purpose of it is to intercept requests and automatically add a Header with your token so that the Polls Application works correctly. If a request fails, it assumes the user isn’t authorized and redirects to the login form. Play around with Postman. As long as you keep the Authorization header you can run through the API endpoints and see what you get. Play with Python Requests. Keep the Django Application running and see if you can write a program using Python Requests that will allow you to login and retrieve some information.

The homework is to help you understand why you would want to use Token Authentication. You can create cool applications external to the Django Application that interface with your API. Give it a go and see what you come up with!

Until next time, Chris