yeti logo icon
Close Icon
contact us
Yeti postage stamp
We'll reply within 24 hours.
Thank you! Your message has been received!
A yeti hand giving a thumb's up
Oops! Something went wrong while submitting the form.

OAuth2 with Django REST Framework

January 20, 2015

UPDATED November 25, 2015

This post is part 2 of a series on using OAuth with Django REST Framework. Part 1 is the series overview and I share some of my thoughts on the process. Part 3 is about social auth (e.g., Facebook, Twitter authentication) using DRF. Part 4 offers a richer explanation of server vs. client oauth flows, and part 5 is about integrating parts 2 & 3.

Here at Yeti we build our APIs with Django REST Framework and use the OAuth2 scheme using Django OAuth Toolkit. I'm no OAuth expert and it took me awhile to figure it all out — in fact, this is the second version of this post! Hopefully this blog post will save others some trouble; it will show you everything you need to set up OAuth2 for your own application using DRF.

This post is NOT about setting up authentication with third-party services like Facebook (see Part 3 instead). It is also not about creating an authentication service for apps other than your own to use.


I'm assuming you already have a User model and have DRF setup.

  1. pip install django-oauth-toolkit
  2. Add 'oauth2_provider' to installed apps
  3. Add DOT to your authentication classes for DRF in
  5. Add DOT to your
  6. urlpatterns = patterns('',
       url(r'^', include(router.urls)),
       url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
       url(r'^admin/', include(,
  7. python migrate

How all this application and client stuff is working

Setting up OAuth for your own application can be confusing. For me, I was used to oauth flows with third-party services like Facebook and Twitter, but it took me a bit to wrap my head around how that would work for my app and our users. It doesn't help that oauth can be implemented in different ways (1.0 vs 2.0, different grant types, etc.).

When you use a third-party service

When you do your own OAuth

Essentially, the way OAuth works, there needs to be an application that a user is authenticating with. But now our app is the service providing authentication, so what is the appilcation supposed to be? Nothing really. It's just a dummy application that we set up. You can think of it as representing your front-end application if that helps.

Creating an application

In your Django admin or shell, you can create a new oauth2_provider.models.Application. Set client type to "public" and grant type to "resource owner password based". The name can just be whatever makes sense to you (e.g., "iOS App", "JS Frontend"), and the application should be owned by your admin user.

Note: The Django OAuth Toolkit tutorial says to make the client type "confidential". You can if you want, but since this app is actually going to be living on a public, insecure client (browser, mobile device), it makes more sense for the client type to be "public".

Example Sign Up

You don't have to use this, you're welcome to just make a user in the admin, but here's a full example:

from rest_framework import serializers

class SignUpSerializer(serializers.ModelSerializer):
   class Meta:
       model = User
       fields = ('username', 'password')
       write_only_fields = ('password',)

from rest_framework import generics
from permissions import IsAuthenticatedOrCreate

class SignUp(generics.CreateAPIView):
   queryset = User.objects.all()
   serializer_class = SignUpSerializer
   permission_classes = (IsAuthenticatedOrCreate,)

from rest_framework import permissions

class IsAuthenticatedOrCreate(permissions.IsAuthenticated):
   def has_permission(self, request, view):
       if request.method == 'POST':
           return True
       return super(IsAuthenticatedOrCreate, self).has_permission(request, view)

urlpatterns = patterns('',
   url(r'^sign_up/$', views.SignUp.as_view(), name="sign_up"),

Request / Response (in JSON)


   "username": "django.pony",
   "password": "djangsta"


   "username": "django.pony"

Get your token

The DOT docs say that you can get your token with the following request:

curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" http://<client_id>:<client_secret>@localhost:8000/o/token/

Let's translate that.

The mechanics of making this request with your Angular / iOS / whatever client are beyond the scope of this blog post, but I use a tool called Postman when playing around with APIs and the request looks like this:

You should get a response that looks like this:

   "access_token": "THIS IS THE IMPORTANT PART",
   "token_type": "Bearer",
   "expires_in": 36000,
   "refresh_token": "xyz456",
   "scope": "read write groups"

Using your token

From here out, using your token is straightforward. To make an authenticated request, just pass the Authorization header in your requests. It's value will be "Bearer YOUR_ACCESS_TOKEN".

Logging in

The last missing piece of this is handling login. If your token expires or a user logs out of your application, you'll need to get a new token. Logging in works the exact same as the last request to /o/token/: you pass client id, grant type, username, and password, and you'll get a fresh access token back.

Logging out

Remember, the only thing that lets the server know that your subsequent requests are authorized is that token you are passing along. To log out (or make an unauthorized request), just delete the access token on your front end.

In summary

These are the endpoints we just set up:

EndpointAuthRequestResponsesign_up/username, passwordusernameo/token/username, password, client_idtoken (and some other stuff)everything elseOAuth2 (formatted as: Bearer YOUR_TOKEN)

You should now be able to sign up, then hit the o/token/ endpoint, and then be on your merry way.

You Might also like...

VIDEO: Building API's with Django and GraphQL

At our last Django Meetup Group event, Jayden Windle, the lead engineer at Jetpack, an on demand delivery company, talks building APIs with Django and GraphQL. Watch the video to learn more.

Using Pytest to Write Beautiful Tests and a Bulletproof Django App

At the last meeting of the San Francisco Django Meetup Group, Wes Kendall gave a talk on how to make a bulletproof Django application by testing it with pytest. Check out his talk here!

Creating a Reusable Component Library: Yeti Lunch and Learn

Part of the Yeti Lunch and Learn series - our amazing developer, Resdan, gives a presentation on creating a reusable component library. Enjoy the video!

Browse all Blog Articles

Ready for your new product adventure?

Let's Get Started