How to Implement OAuth2 using Django REST Framework

Let’s paint a picture for you. You want to create a web and mobile application that allows your users to login more securely than Token Authentication. You know it’s possible, but you’re not sure how to implement something like this.

We can also use Facebook, Google, Twitter, Github, etc. to authenticate users. However, I’m just going to describe how to use OAuth to authenticate with JUST our application.

Maybe there is a package you can use? You’d be correct. There is a package you can use. OAuth Authentication implementation from scratch is complicated. Therefore, I recommend NOT re-inventing the wheel. I recommend using a package that already implements it. (I’ll write a post about how OAuth can be implemented yourself, if you’re interested in learning how this works).

I’m just going to pick a random OAuth package because it really doesn’t matter. The implementation of OAuth is the same no matter which package you choose. In this case, I’m going to use django-rest-framework-social-oauth2.

Implementing OAuth2 using Django-REST-Framework-Social-OAuth2

Let’s start by installing the package.

$ pip install django-rest-framework-social-oauth2

Now, let’s add the package apps to our INSTALLED_APPS.

settings.py

INSTALLED_APPS = (
    #...
    'oauth2_provider',
    'social_django',
    'rest_framework_social_oauth2,
)

Next, let’s include the URLs to our urls.py.

urls.py

urlpatterns = patterns(
    # ...
    url(r'^auth/', include('rest_framework_social_oauth2.urls')),
)

Now, we need to set up the packages CONTEXT_PROCESSORS. If you are using Django 1.8+ you’ll add the CONTEXT_PROCESSORS in the TEMPLATES setting.

settings.py

TEMPLATES = [
    {
        # ...
        'OPTIONS': {
            'context_processors': [
                # ...
                'social_django.context_processors.backends',
                'social_django.context_processors.login_redirect',
            ],
        },
    }
]

However, if you are using anything BEFORE Django 1.8, you’ll need to add the context processors like so…

settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    # ...
    'social_django.context_processors.backends',
    'social_django.context_processors.login_redirect',
)

Now, we need some Authentication Backends so that Django and REST knows how to authenticate users. So, let’s add the backends to both settings.

settings.py

# DJANGO REST FRAMEWORK SETTINGS
REST_FRAMEWORK = {
    # ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # ...
        'oauth2_provider.ext.rest_framework.OAuth2Authentication',
        'rest_framework_social_oauth2.authentication.SocialAuthentication',
    ),
}

# DJANGO SETTINGS 
AUTHENTICATION_BACKENDS = (
    # ...
    'rest_framework_social_oauth2.backends.DjangoOAuth2',
    'django.contrib.auth.backends.ModelBackend',
)

Set up Web Application

We have successfully setup our application to use OAuth2 in our Web Application. Just like every time you add a new app to your list of INSTALLED_APPS, you always need to run:

$ python manage.py migrate

This command will build our database backend with the new models from the OAuth2 package.

Let’s run the application!

$ python manage.py runserver

If the application starts correctly, we’ll go to http://localhost:8000/admin/ and login with:

username: adminadmin 
password: adminadmin

When you login successfully, you’ll see a list of different options: Django OAuth Toolkit and Social_Django.

Underneath Django OAuth Toolkit, near Applications, click Add.

Your application should be filled out to be the following:

Client Id: **Do not change**
User: **click the hourglass and select the superuser**
Redirect URIs: **leave blank**
Client Type: “Confidential”
Authorization grant type: “Resource owner password-based”
Client secret: **Do not change**
Name: **Anything you want — maybe “Test Example”**

Next, click save to save that application.

Test the Application

Use either CURL (command line) or use Postman to create a POST request to your web application (http://localhost:8000/auth/token using the following information:

username=adminadmin
password=adminadmin
client_id=QKaPafSal2lYYfIYIDSKCC3hoj0TRPLFnZYJNE0h
client_secret=bvQDk9bIwVS28VSNZFP5ehgsrnQroWP5xHccdradOvqxonWSqC1soy7HzaiIiRzCQi73o0pPKyWp7dEoS8DgrZWLoiwJf7iZ8kymv1rb1s3Hx3XSTGQgDmVBqveOQT5H
grant_type=password

If you are using CURL, you can run the following command:

$ curl -X POST -d "client_id=QKaPafSal2lYYfIYIDSKCC3hoj0TRPLFnZYJNE0h&client_secret=bvQDk9bIwVS28VSNZFP5ehgsrnQroWP5xHccdradOvqxonWSqC1soy7HzaiIiRzCQi73o0pPKyWp7dEoS8DgrZWLoiwJf7iZ8kymv1rb1s3Hx3XSTGQgDmVBqveOQT5H&grant_type=password&username=adminadmin&password=adminadmin" http://localhost:8000/auth/token

If you are using Postman, your interface should look like this:

This will retrieve a secret token for use for authentication by our user.

Now, we need to use the access token that we received and create an Authorization header in the form:

Authorization: Bearer [access_token]

The access token that I received happens to look like this: 71AVaiCidnYcD2ct3Mqgat9j4jo6Xl.

So, if I want to access http://localhost:8000/polls/api/questions/1 I have to create a header using my access token in order to access that question.

In CURL, I would do something like this:

$ curl -H "Authorization: Bearer 71AVaiCidnYcD2ct3Mqgat9j4jo6Xl" -X GET http://localhost:8000/polls/api/questions/1

In Postman I do something like this:

Just to test it out to make sure that I’m doing this right, I will remove the Header from the request and see if Django will let me access the data. Not surprisingly, it doesn’t let me in!

Click here for my Sample Code — remember to install the package using pip

Homework (because this helps you apply what you learned)

  1. Setup a new Django REST Framework web application
  2. Add an endpoint, a serializer and make sure only authenticated users can access the data.
  3. Follow the steps above and try OAuth2 out for yourself. Get it to work.
  4. If you have questions email me

Now, you know how to implement OAuth2 in your own application. You can use the similar steps to get this setup for Facebook, Google, Twitter, Github, etc. so you can allow users to sign in to your application using accounts that they already have and use!

Try this out, see if you can get it work for yourself!

Learn Django REST Framework FREE!

Get started learning Django REST Framework today.

Each email will contain a full length lesson that will have you mastering Django REST Framework in no time!

Join today!

Powered by ConvertKit