Integrating Auth0 with DRF

A couple of months I started my first project with Auth0.

We had a RESTful application, and my team lead went and told me to integrate our authentication system with Auth0.

I was confused because most of the work was done in the front end, and I just didn't know what to do.

I went on to the documentation, it was pretty complicated.

Finally after hours of research, and trial and error.

I got something working.

I don't want you to go through the same.

That's why let's talk about how to practically integrate Auth0 with a RESTful Backend using Django Rest Framework.

Prerequisites

  • Basic Knowledge of Python
  • Basic Knowledge of Django and Django Rest Framework

Common Terminology

  • Authentication – Process of verifying who a user is.
  • Authorization – Process of verifying what the user has access to.
  • Client – Any device that sends requests to our backend. This can be a frontend web app or a native mobile app.

What is Auth0?

Auth0 is a third party service that outsources your authentication and authorization needs.

It's one of its kind, the are many other cloud providers that do that such as AWS and Firebase. Unlike others, Auth0 strictly works on authentication and authorization.

Why Auth0?

Another interesting question is why would you choose Auth0 over other competitors.

Auth0 excels over its competitors in terms of:

  • Security – Auth0 security is provided by OAuth 2.0 authentication protocol.
  • UI Options – Auth0 natively makes very good looking UI options for authentication. This makes it very easy to plug Auth0 into your frontend app. They also allow you to customize UI based on your needs.
  • Analytics – Auth0 provides very intensive data based on user activity.
  • Customizability – Auth0 is very customizable there are many different configs based on your architecture.
  • Developer Support – Auth0 has great documentation and provides SDKs for many popular programming languages. It also provides official videos, articles, and has an active community forum.

Auth0 Authentication and Authorization Flows

Before we begin directly integrating Auth0 into our Django application. We should go over the various authorization flows that Auth0 provides us.

Authentication flows are different ways that the user can authenticate.

Currently, Auth0 uses the OAuth2 Authorization Framework that provides seven authorization flows.

Authorization Code Flow

Source: https://auth0.com/docs/authorization/flows/authorization-code-flow

This is the simplest flow and the one that we are going to implement today.

This is used for regular web apps, where the fronted will directly communicate with the Auth0 API to authenticate.

Once authentication is done, Auth0 will send back the user a token in which our backend can verify using Auth0 SDKs.

Authorization Code Flow with Proof Key for Code Exchange

Source: https://auth0.com/docs/authorization/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce

This is similar to authorization code flow but is a bit more secure.

The main difference between this and the regular authorization code flow is that clients aren't required to provide client_secret

This is considered best practice for single-page applications and native mobile apps.

Implicit Flow with Form Post

Source: https://auth0.com/docs/authorization/flows/implicit-flow-with-form-post

Implicit flow is a browser only flow and it's less secure than code flow since it doesn't authentication the client.

It's useful for applications that still need access tokens but don't have a backend.

Hybrid Flow

Hybrid flow is an authorization flow that is inspired by both code flow and implicit flow.

This is useful for clients who can securely store their credentials because you can immediately get access to an ID token while maintaining security for all access and refresh tokens.

Client Credentials Flow

Source: https://auth0.com/docs/authorization/flows/client-credentials-flow

Client credentials flow is mostly used for machine to machine communication such as CLIs, services, daemons, etc...

Because things such as username and password are meaningless for machines, we authorize using client credentials.

Device Authorization Flow

Source: https://auth0.com/docs/authorization/flows/device-authorization-flow

Device authorization flow is used for input constrained devices such as smartwatches. The basic premise is that instead of authenticating the user directly. It will provide a link for the user to authenticate using their smartphone or computer.

Resource Owner Password Flow

Source: https://auth0.com/docs/authorization/flows/resource-owner-password-flow

This is authentication using username and password, it's not recommended due to security reasons.

Which Flow should I use?

Auth0 has a great article on how to choose authentication flows, you can check it out here.

Which OAuth 2.0 Flow Should I Use?
Learn how to identify the proper OAuth 2.0 flow for your use case.

If you are too lazy to read here is the TLDR version.

  • If your client is a machine then use the Client Credentials Flow.
  • If your client is a machine and the resource owner, then no authentication is needed.
  • If your client is a regular web app, then use Authentication Code Flow.
  • If your client is a single page application or mobile app, then use Authorization Code Flow with Proof Key for Code Exchange.
  • If your client is a single page application that does not need access tokens then use Implicit Flow with Form Post
  • If your client is trusted with user credentials then use Resource Owner Password Flow.

Integrating Auth0 to Django

For this application, we will use authorization code flow.

Our client is already authenticated using Auth0 and has an access token.

Our job in the backend is to authorize this backend token.

The only thing that you need is your Auth0 Domain which can be found in your application settings in Auth0 Management.

Once you have that down install the official Auth0 python SDK.

pip install auth0-python

Let's create a simple function that validates a JWT token.

from auth0.v3.authentication.token_verifier import AsymmetricSignatureVerifier, TokenValidationError


AUTH0_DOMAIN = settings.AUTH0_DOMAIN
AUTH0_JWKS = 'https://{}/.well-known/jwks.json'.format(AUTH0_DOMAIN)

def validate_token(token):
	signiture_verifier = AsymmetricSignatureVerifier(AUTH0_JWKS)
    try:
    	jwt_payload = signiture_verifier(token)
        return True
    except TokenValidationError:
    	return False

Our JWT Token by default is in RSA 256 format, to validate that we need our public key, which is available at our jwks.json in Auth0.

We simply provided SignatureVerifier with our public key, which allows us to validate our token.

This is pretty simple, now you can create a custom authentication backend using this function.

Conclusion

Auth0 is a great service, but sometimes can be a bit overwhelming.

Hopefully, by the end of the article, you have a faint idea of how to integrate Auth0 with your system.

If you got any questions feel free to message me on @tamerlan_dev.