Django Integration#

Looking for OAuth 2.0 server?

The Django client handles OAuth 2.0 services. Authlib has a shared API design among framework integrations. Get started with Web Clients.

Create a registry with OAuth object:

from authlib.integrations.django_client import OAuth

oauth = OAuth()

The common use case for OAuth is authentication, e.g. let your users log in with Twitter, GitHub, Google etc.

Important

Please read Web Clients at first. Authlib has a shared API design among framework integrations, learn them from Web Clients.

Configuration#

Authlib Django OAuth registry can load the configuration from your Django application settings automatically. Every key value pair can be omitted. They can be configured from your Django settings:

AUTHLIB_OAUTH_CLIENTS = {
    'github': {
        'client_id': 'GitHub Client ID',
        'client_secret': 'GitHub Client Secret',
        'access_token_url': 'https://github.com/login/oauth/access_token',
        'authorize_url': 'https://github.com/login/oauth/authorize',
        'api_base_url': 'https://api.github.com/',
        'client_kwargs': {'scope': 'user:email'},
    }
}

Please check the parameters in .register in Web Clients.

Routes for Authorization#

Just like the example in Web Clients, everything is the same. But there is a hint to create redirect_uri with request in Django:

def login(request):
    # build a full authorize callback uri
    redirect_uri = request.build_absolute_uri('/authorize')
    return oauth.twitter.authorize_redirect(request, redirect_uri)

Auto Update Token via Signal#

Instead of defining an update_token method and passing it into OAuth registry, it is also possible to use signals to listen for token updates:

from django.dispatch import receiver
from authlib.integrations.django_client import token_update

@receiver(token_update)
def on_token_update(sender, name, token, refresh_token=None, access_token=None, **kwargs):
    if refresh_token:
        item = OAuth2Token.find(name=name, refresh_token=refresh_token)
    elif access_token:
        item = OAuth2Token.find(name=name, access_token=access_token)
    else:
        return

    # update old token
    item.access_token = token['access_token']
    item.refresh_token = token.get('refresh_token')
    item.expires_at = token['expires_at']
    item.save()

Django OpenID Connect Client#

An OpenID Connect client is no different than a normal OAuth 2.0 client. When registered with the openid scope, the built-in Django OAuth client will handle everything automatically:

oauth.register(
    'google',
    ...
    server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
    client_kwargs={'scope': 'openid profile email'}
)

When we get the returned token:

token = oauth.google.authorize_access_token(request)

There should be a id_token in the response. Authlib has called .parse_id_token automatically, we can get userinfo in the token:

userinfo = token['userinfo']

RP-Initiated Logout#

To implement OpenID Connect RP-Initiated Logout, use the logout_redirect method to redirect users to the provider’s end session endpoint:

def logout(request):
    # Retrieve the ID token you stored during login
    id_token = request.session.pop('id_token', None)
    redirect_uri = request.build_absolute_uri('/logged-out')
    return oauth.google.logout_redirect(
        request,
        post_logout_redirect_uri=redirect_uri,
        id_token_hint=id_token,
    )

def logged_out(request):
    state_data = oauth.google.validate_logout_response(request)
    return HttpResponse('You have been logged out.')

The logout_redirect method accepts:

  • request: The Django request object (required)

  • post_logout_redirect_uri: Where to redirect after logout (must be registered with the provider)

  • id_token_hint: The ID token previously issued (recommended)

  • state: Opaque value for CSRF protection (auto-generated if not provided)

  • client_id: OAuth 2.0 Client Identifier (optional)

  • logout_hint: Hint about the user logging out (optional)

  • ui_locales: Preferred languages for the logout UI (optional)

Note

You must store the id_token during login to use it later for logout. The id_token is available in token['id_token'] after calling authorize_access_token().

Find Django Google login example at https://github.com/authlib/demo-oauth-client/tree/master/django-google-login