Setup OAuth2 client for Django in 5 minutes

Setup OAuth2 client for Django in 5 minutes

This article explains how to setup OAuth2 client for Django in 5 minutes, it’s used for Web service which requires user to login by OAuth2, especially for those who are familiar with OAuth2.0 but unfamiliar with Django.

If you have no idea about OAuth2.0 workflow, please visit OAuth2 net

The example here introduces Web service implements the OAuth2 workflow, the user must login first then he can see the web content. The Web Framework is Python Django, the OAuth library we use is Authlib==0.14.1. It supports user session persistence and auto-refresh access_token.

OAuth configuration

If we consider using Github as the authorization server, first you need to register a new OAuth application in Github, then you’ll have you credentials.
Secondly, setup OAuth settings in settings.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# OAuth Settings
OAUTH_URL_WHITELISTS = []

OAUTH_CLIENT_NAME = 'github'

OAUTH_CLIENT = {
'client_id': '',
'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/',
'redirect_uri': 'https://songrgg.com/oauth/callback',
'client_kwargs': {
'scope': 'profile email',
'token_placement': 'header'
},
'userinfo_endpoint': 'user',
}

Pay attention, the redirect uri should be the one your server will use to fetch access token and setup user session, I setup /oauth/callback here, the logic will be introduced in middleware.

Middleware

For each user request, the server will check user’s session and see if user has logined, in both Django or other Web frameworks, we could setup middleware to handle user requests.

Initialize the OAuth client

Use the OAuth configuration to initialize the OAuth client.

1
2
3
4
5
6
7
def update_token(token, refresh_token, access_token):
request.session['token'] = token
return None

sso_client = self.oauth.register(
settings.OAUTH_CLIENT_NAME, overwrite=True, **settings.OAUTH_CLIENT, update_token=update_token
)

update_token parameter is used to refresh the access_token when it’s expired.

Process OAuth callback

After the user authorizes the login, our server should fetch the access_token from the authorization server and store it in user session.

1
2
3
4
5
6
7
8
if request.path.startswith('/oauth/callback'):
self.clear_session(request)
request.session['token'] = sso_client.authorize_access_token(request)
if self.get_current_user(sso_client, request) is not None:
redirect_uri = request.session.pop('redirect_uri', None)
if redirect_uri is not None:
return redirect(redirect_uri)
return redirect(views.index)

Fetch user info

After the access_token is ready, fetch the user info from the resource API, otherwise redirect user to the authorization page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@staticmethod
def get_current_user(sso_client, request):
token = request.session.get('token', None)
if token is None or 'access_token' not in token:
return None

if not OAuth2Token.from_dict(token).is_expired() and 'user' in request.session:
return request.session['user']

try:
res = sso_client.get(settings.OAUTH_CLIENT['userinfo_endpoint'], token=OAuth2Token(token))
if res.ok:
request.session['user'] = res.json()
return res.json()
except OAuthError as e:
print(e)
return None

Put the middleware

In settings.py, put the middleware class to the array.

1
2
3
MIDDLEWARE = [
'oauth_demo.middleware.oauth.OAuthMiddleware'
]

Session

We use Django session module and the default storage is sqlite3, you can simply change it to other backends like redis by modifying settings.py.

Conclusion

The full repository is located at https://github.com/songrgg/oauth-demo.

Comments

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×