In this article, you are building REST API endpoints for social authentication. They can be used with a separate frontend like a Single-Page or Mobile Application. We will be using together with (DRF) to exchange an access token obtained by a third-party OAuth provider (GoogleOAuth2) with an authentication token from DRF.
Note: We will only work with API endpoints and not be using Djangos' built-in template language in this example.
Authentication with OAuth2 offers different flows, depending on the specific setup you are using for your application. The basics and which flow to choose for your project are covered well in these two articles from and .
In this example, we are using the , which is the recommended way when public clients, like Single-Page and Mobile Applications, request an access token from an OAuth2 provider. The authentication process with the provider happens on the client, which after successful authentication exchanges the received access token for another authentication token from the backend. With this token, the client can then be authenticated to use the APIs provided by the backend.
Further details about this flow are well explained in this . The exception in our case is, that we are connecting directly to GoogleOAuth2, instead of Auth0.
Is this the right social authentication package for me? Note: If you are unsure if this is the best package for your use case, you can find a brief comparison between four popular social authentication packages for Django in .
PrerequisitesBefore we start I am asking you to install and set up your Django project. If you are unsure of how to do that, please check the ‘’-documentation.
We are using (DRF) for setting up the REST API endpoints and a basic understanding of it is recommended. The scope of this Article will not cover much about DRF itself, however, the information provided in its ‘’-Tutorial will be more than enough to follow along here.
To test your application you will need a GoogleOAuth2 access token. This would usually be obtained by your frontend, like a Single-Page or Mobile Application. For development purposes, you can also do that by using a web browser and curl, as described .
Note: Make sure to request the required scope to adequately populate your user model, when sending the OAuth request with the client. For GoogleOAuth2 it is: scope = ['email', 'profile'] .
Getting StartedAssuming that you have set up your Django Project and have already applied your initial migrations, let’s start by adding a new app called users. In there we are building our authentication logic:
python manage.py startapp usersNext, we install the required third-party packages.
pip install django \djangorestframework \social-auth-core \social-auth-app-djangoAfter installation, we register the users and external apps in our settings.py:
Finally, we run the migrations that come with and .
python manage.py migrateFor PostgreSQL users: In this example, we are using the SQLite3 database, that Django uses by default. If you are working with a PostgreSQL database, it is recommended to use the built-in JSONB field for storing the extracted extra_data , by adding this line to your settings.py: SOCIAL_AUTH_JSONFIELD_ENABLED = True
For MongoEngineORM users: If you are using the ORM, installation and setup vary slightly. Please check .
ConfigurationFor DRF we are adding a few entries into our settings.py to define authentication and permission classes.
Settings for DRF
Authentication By adding rest_framework.authtoken to our INSTALLED_APPS and adding TokenAuthentication to the list of default authentication classes, we enabled . It provides a simple token-based HTTP Authentication scheme.
In our example, we are exchanging the access token received from the social provider in our frontend for one of these tokes. It can then be used to authenticate against our protected API endpoints.
Note: This is not a very secure authentication scheme and is used only for presentation purposes. For production-level applications, you want to consider a more secure alternative.
Permissions By default, all API requests need to be authenticated with this setting. We can change this behavior on APIs that are intended to be public, later on.
Django keeps a list of authentication backends, to iterate through on an authentication request. It defaults to Django’s basic authentication backend but can be . In this example, we are adding a backend for authentication. You can find a full list of available options with python-social-auth, .
Note: If the entry AUTHENTICATION_BACKENDS does not exist, you must create it yourself.
are used to handle authentication, association, and disconnection flows in python-social-auth. Default flows exist for these pipelines and can be adjusted as required (Adding custom functions; Removing default items).
The default authentication pipeline can be found, . To define your own, you can add it to your settings.py.
Note: In this example, we use the default pipeline, without adding our own version. However, you can find an example version below.
We will use a registration endpoint to register/login a user with an access token from a social provider (GoogleOAuth2). This endpoint will be open to the public. Furthermore, we are defining a second endpoint that can be used with the authentication tokens handed out by our backend.
The @psa() decorator is the key piece of our view. It connects our view with and adds details to the request object.
Note: Unfortunately, the @psa() decorator is barely mentioned in the official documentation of , but some additional information can be found in this .
With the access token obtained from our client we can now test our API:
curl -X POST \http://127.0.0.1/api/register-by-access-token/social/google-oauth2/ \-H 'Accept: application/json' \-H 'Content-Type: application/json' \-d '{"access_token": "<GoogleOAuth2-ACCESS-TOKEN-FROM-CLIENT>"}'This should yield something like: {"token": "<TOKEN-FROM-BACKEND"} .
Using the received authentication token from our backend, we can now access the protected endpoint.
curl \http://127.0.0.1/api/authentication-test/ \-H 'Accept: application/json' \-H 'Content-Type: application/json' \-H 'Authorization: Token fd4d4cca9163e5afb251f6310b9c725413979f10'{"message": "User successfully authenticated"}
SummaryYou now have a simple REST API endpoint to create and log in Google users. To receive access, simply exchange an access token obtained with your frontend for an authentication token of your backend. To use other authentication providers like Facebook or Twitter, follow the same principle with a different authentication backend.
I Love PHP