Integrating Social Backends

For each authentication provider, the top portion of your REST API settings.py file should look like this:

INSTALLED_APPS = (
    ...
    # OAuth
    'oauth2_provider',
    'social_django',
    'drf_social_oauth2',
)

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

REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        ...
        # OAuth
        # 'oauth2_provider.ext.rest_framework.OAuth2Authentication',  # django-oauth-toolkit < 1.0.0
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',  # django-oauth-toolkit >= 1.0.0
        'drf_social_oauth2.authentication.SocialAuthentication',
    )
}

Listed below are a few examples of supported backends that can be used for social authentication.

For each integration for every single backend, you need to add a new application for each corresponding social backend. See the Setting Up a New Application section. This means that if you are authenticating with Facebook and Google, you have to create two applications in the Application section in your Django Admin dashboard.

Facebook Integration

To use Facebook as the authorization backend of your REST API, your settings.py file should look like this:

AUTHENTICATION_BACKENDS = (
    # Others auth providers (e.g. Google, OpenId, etc)
    ...

    # Facebook OAuth2
    'social_core.backends.facebook.FacebookAppOAuth2',
    'social_core.backends.facebook.FacebookOAuth2',

    # drf_social_oauth2
    'drf_social_oauth2.backends.DjangoOAuth2',

    # Django
    'django.contrib.auth.backends.ModelBackend',
)

# Facebook configuration
SOCIAL_AUTH_FACEBOOK_KEY = '<your app id goes here>'
SOCIAL_AUTH_FACEBOOK_SECRET = '<your app secret goes here>'

# Define SOCIAL_AUTH_FACEBOOK_SCOPE to get extra permissions from Facebook.
# Email is not sent by default, to get it, you must request the email permission.
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
    'fields': 'id, name, email'
}

To test your REST API’s settings, you can execute the following command:

$ curl -X POST -d "grant_type=convert_token&client_id=<client_id>&backend=facebook&token=<facebook_token>" http://uri:port/auth/convert-token

This command will return an access_token that you should use for every HTTP request to your API. The purpose of this process is to convert a third-party access token (user_access_token) into an access token that you can use with your API and its clients (access_token). By doing so, you will be able to authenticate each request and avoid authenticating with Facebook every time.

You can obtain the ID (SOCIAL_AUTH_FACEBOOK_KEY) and secret (SOCIAL_AUTH_FACEBOOK_SECRET) of your app from https://developers.facebook.com/apps/.

For testing purposes, you can utilize the access token user_access_token from https://developers.facebook.com/tools/accesstoken/.

If you require further information on how to configure python-social-auth with Facebook, visit http://python-social-auth.readthedocs.io/en/latest/backends/facebook.html.

Google Integration

To use Google OAuth2 as the authorization backend of your REST API, your settings.py file should look like this:

AUTHENTICATION_BACKENDS = (
    # Others auth providers (e.g. Facebook, OpenId, etc)
    ...
    # Google  OAuth2
    'social_core.backends.google.GoogleOAuth2',
    # drf-social-oauth2
    'drf_social_oauth2.backends.DjangoOAuth2',
    # Django
    'django.contrib.auth.backends.ModelBackend',
)

# Google configuration
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = <your app id goes here>
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = <your app secret goes here>

# Define SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE to get extra permissions from Google.
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
]

To test the configuration settings, execute the following command:

$ curl -X POST -d "grant_type=convert_token&client_id=<django-oauth-generated-client_id>&backend=google-oauth2&token=<google_token>" http://uri:port/auth/convert-token

Upon successful execution, the above command returns an access_token that you must utilize for each HTTP request made to your REST API. In essence, what is happening here is that you are converting a third-party access token (user_access_token) into an access token that can be used with your API and its clients (access_token). For each subsequent communication between your system/application and your API, it is necessary to use this token to authenticate each request, thereby avoiding the need to authenticate with Google every time.

To obtain your app’s ID (SOCIAL_AUTH_GOOGLE_OAUTH2_KEY) and secret (SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET), visit https://console.developers.google.com/apis/credentials. For more details on how to create an ID and secret, visit https://developers.google.com/identity/protocols/OAuth2.

For testing purposes, you can use the access token user_access_token from https://developers.google.com/oauthplayground/ and follow these steps:

For more information on configuring python-social-auth with Google, please visit https://python-social-auth.readthedocs.io/en/latest/backends/google.html#google-oauth2.

Should you prefer a step-by-step tutorial, refer to this link provided by @djangokatya: https://djangokatya.com/2021/04/09/social-login-for-django-rest-framefork-for-newbies-a-k-a-for-me/.

Google OpenID Integration

OpenID and access tokens are two different concepts that are used in authentication and authorization systems.

OpenID is an open standard that allows users to authenticate with multiple websites and applications using a single set of credentials. When a user logs in using OpenID, they are redirected to their OpenID provider, which authenticates them and provides the website or application with a unique identifier for the user. The identifier can be used to retrieve the user’s profile information, but it does not provide any authorization to access APIs or services.

Access tokens, on the other hand, are used to authorize API requests on behalf of the user. When a user logs in and grants permission to access their data, an access token is generated and returned to the client application. The access token is used to authenticate the client application and authorize it to make API requests on behalf of the user. The access token contains information such as the permissions granted to the client application, the expiration time, and a signature that verifies the token’s authenticity.

In summary, OpenID is used to authenticate users and provide a unique identifier for them, while access tokens are used to authorize API requests on behalf of the user. While OpenID and access tokens are both important components of authentication and authorization systems, they serve different purposes and should not be confused with each other.

In order to authenticate with Open ID, proceed as follows:

AUTHENTICATION_BACKENDS = (
    # Others auth providers (e.g. Facebook, OpenId, etc)
    ...
    # Google  OAuth2
    'drf_social_oauth2.backends.GoogleIdentityBackend',
    # drf-social-oauth2
    'drf_social_oauth2.backends.DjangoOAuth2',
    # Django
    'django.contrib.auth.backends.ModelBackend',
)

# Google configuration
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = <your app id goes here>
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = <your app secret goes here>

# REQUIRED. The Google OAuth client ID(s) whose ID tokens this application
# accepts. See "Validating the ID token audience" below.
SOCIAL_AUTH_GOOGLE_IDENTITY_AUDIENCE = <your google oauth client id goes here>

# Define SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE to get extra permissions from Google.
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
]

Validating the ID token audience

Google’s tokeninfo endpoint tells you that an ID token is validly signed and unexpired. It cannot tell you that the token was issued to your application, because it has no idea which application is asking. Checking that is the relying party’s job, and GoogleIdentityBackend does it by comparing the token’s aud claim against the client ID(s) you configure.

This matters because anyone can register a Google OAuth client for free. If the audience were not checked, an attacker could stand up their own “Sign in with Google” page, have a victim sign in there once, and replay the resulting ID token — which carries the victim’s email address — against your /convert-token/ endpoint. Since the social UID is derived from that email, your application would issue a real access token for the victim’s account. This was GHSA-c6x8-38vf-4p8r, fixed in 3.4.2.

The accepted audience is read from the first of these settings that is set:

  1. SOCIAL_AUTH_GOOGLE_IDENTITY_AUDIENCE

  2. SOCIAL_AUTH_GOOGLE_IDENTITY_KEY

  3. SOCIAL_AUTH_GOOGLE_OAUTH2_KEY

If none of them is set, the backend raises ImproperlyConfigured rather than accepting the token, because there is nothing to validate against. Note that releases up to 3.4.1 documented only SOCIAL_AUTH_GOOGLE_OAUTH2_KEY for this backend, so existing deployments keep working via entry 3 — but prefer setting SOCIAL_AUTH_GOOGLE_IDENTITY_AUDIENCE explicitly.

Native apps typically have one client ID per platform, and Google mints each platform’s ID tokens with that platform’s client ID in aud. Pass a list to accept all of them:

SOCIAL_AUTH_GOOGLE_IDENTITY_AUDIENCE = [
    '<web client id>.apps.googleusercontent.com',
    '<ios client id>.apps.googleusercontent.com',
    '<android client id>.apps.googleusercontent.com',
]

Only list client IDs your own organization controls. Every client ID you add is an application whose ID tokens are accepted as proof of identity here.

The backend also rejects tokens whose iss is not Google and tokens whose email_verified claim is not true — an unverified address would let a token holder claim a mailbox they do not control.

For testing purposes, you can use the id token id_token from https://developers.google.com/oauthplayground/.

  1. Visit the OAuth 2.0 Playground.

  2. Select Google OAuth2 API v2 and authorize for openid.

  3. Exchange Authorization code for tokens and get an id token.

  4. Use the id token as the token parameter in the /convert-token endpoint.

By default the Playground mints tokens under Google’s own Playground client ID, so as of 3.4.2 those tokens are rejected with access_denied — the audience does not name your application. This rejection is the audience check working as intended, not a misconfiguration. To test with a Playground token, open the Playground’s settings (“Use your own OAuth credentials”) and enter your own OAuth client ID and secret, so the token is minted for your application.

If you want to inspect an id token’s claims — including the aud value the backend compares against — copy it and hit this url, https://oauth2.googleapis.com/tokeninfo?id_token=your_token_here.

To test the configuration settings, execute the following command:

$ curl -X POST -d "grant_type=convert_token&client_id=<django-oauth-generated-client_id>&backend=google-identity&token=<google_openid_token>" http://uri:port/auth/convert-token

Github Integration

AUTHENTICATION_BACKENDS = (
    # Others auth providers (e.g. Facebook, OpenId, etc)
    ...

    # GitHub OAuth2
    'social_core.backends.github.GithubOAuth2',

    # drf-social-oauth2
    'drf_social_oauth2.backends.DjangoOAuth2',

    # Django
    'django.contrib.auth.backends.ModelBackend',
)

# GitHub configuration
SOCIAL_AUTH_GITHUB_KEY = <your app id goes here>
SOCIAL_AUTH_GITHUB_SECRET = <your app secret goes here>

You need to register a new GitHub app at https://github.com/settings/applications/new. set the callback URL to http://example.com/complete/github/ replacing example.com with your domain.

The Client ID should be added on SOCIAL_AUTH_GITHUB_KEY and the SOCIAL_AUTH_GITHUB_KEY should be added on SOCIAL_AUTH_GITHUB_SECRET.

As described by GitHub’s documentation, you need to follow a few steps in order to generate the access token to post requests on behalf of a user, team or organisation. The first step, your application will need to Request a user’s GitHub identity by sending a GET request to

https://github.com/login/oauth/authorize

The only compulsory parameters are client_id=<the app client id> and redirect_uri=<the redirect you added in your app>. You will be redirected to a new location in your browser, such as http://example.com/complete/github?code=d9ba2b356d27455970bf, copy the code=value from it. Remember, this is only value for 10 minutes. This process should be automated by the module/library integrated in your front end application.

The second step is to send a request to:

$ curl -X POST -d "client_id=<client id>&client_secret=<client secret>&code=<code from previous step>&redirect_uri=<your redirect uri>" https://github.com/login/oauth/access_token

You should receive an access token from the previous step. Once you have the access token, test your configuration

Now, visit https://github.com/settings/tokens and create a new token. Select the user checkbox, as to grant user access. The click on the Generate Token button. Use the access token as the token parameter in the /convert-token endpoint.

To test the configuration settings, execute the following command:

$ curl -X POST -d "grant_type=convert_token&client_id=<django-oauth-generated-client_id>&backend=github&token=<github_token>" http://uri:port/auth/convert-token

Read more about GitHub’s configuration at Python Social Auth - Github Page

Instagram Integration

Before setting up any configuration in your settings.py file, you need to create an application in your Meta For Developers dashboard. Follow these guidelines in order to create and configure your application. The steps are easy to follow. Proceed until step 6.

Configure your settings.py as follows:

AUTHENTICATION_BACKENDS = (
    # Others auth providers (e.g. Facebook, OpenId, etc)
    ...

    # Instagram OAuth2
    'social_core.backends.instagram.InstagramOAuth2',

    # drf-social-oauth2
    'drf_social_oauth2.backends.DjangoOAuth2',

    # Django
    'django.contrib.auth.backends.ModelBackend',
)

# Instagram configuration
SOCIAL_AUTH_INSTAGRAM_KEY = <your app id goes here>
SOCIAL_AUTH_INSTAGRAM_SECRET = <your app secret goes here>
SOCIAL_AUTH_INSTAGRAM_AUTH_EXTRA_ARGUMENTS = {'scope': 'likes comments relationships'}

Once you finished setting up the configuration in your project, copy the access token generated at step 5 (from facebook guidelines). Step 5 will return a response as follows:

{
  "access_token": "IGQVJ...",
  "user_id": 17841405793187218
}

Copy the access token and use it in the token parameter in your /auth/convert-token endpoint. To test the configuration settings, execute the following command:

$ curl -X POST -d "grant_type=convert_token&client_id=<django-oauth-generated-client_id>&backend=instagram&token=<access_token>" http://uri:port/auth/convert-token

LinkedIn Integration

Before setting up any configuration in your settings.py file, you need to create an application in your Linked Developers dashboard. Visit the Linked Developer Page in order to create and configure your application.

For more information on how to create a new app, visit these guidelines Once your app is created, visit the Token Generator page and create a token.

Copy the access token and use it in the token parameter in your /auth/convert-token endpoint. To test the configuration settings, execute the following command:

$ curl -X POST -d "grant_type=convert_token&client_id=<django-oauth-generated-client_id>&backend=linkedin-openidconnect&token=<access_token>" http://uri:port/auth/convert-token

Note that: Linked In has discontinued Oauth2 since August 2023. They are using OpenID Connect instead.

Configure your settings.py as follows:

AUTHENTICATION_BACKENDS = (
    # Others auth providers (e.g. Facebook, OpenId, etc)
    ...

    # Linked OpenID
    'drf_social_oauth2.backends.LinkedInOpenIDUserInfo',

    # drf-social-oauth2
    'drf_social_oauth2.backends.DjangoOAuth2',

    # Django
    'django.contrib.auth.backends.ModelBackend',
)

# Instagram configuration
SOCIAL_AUTH_LINKEDIN_OPENIDCONNECT_KEY = 'key goes here'
SOCIAL_AUTH_LINKEDIN_OPENIDCONNECT_SECRET = 'secret goes here'

Other Backend Integration

DRF-Social-Oauth2 is not only limited to Google, Facebook, Instagram, Github and LinkedIn. You can integrate with every backend described at the Python Social Oauth backend integrations.