Auth0 implementation with flask framework
Auth0 implementation with flask framework
14 January 2021
This blog will demonstrate how to add user login to a web application built with the Flask framework. We will recommend you to follow this article with examples configured for your account with Auth0.
Prerequisite
- Python 2.7, 3.0
- Flask 0.10.1
- Python-dotenv
- Requests
- Flask-oauthlib
- Six 1.10.0
Auth0 Configuration
Generate Application Keys:
When a user signs up for Auth0, a new application will be created or you can create a new application as per the requirements.
You will need to fill-in the details about your application to communicate with Auth0. We can fetch details from the Auth0 dashboard section.
There is the following information that is required for the communication :
- Domain
- Client ID
- Client Secret
After generating the application credentials we need to set up the callback URL in the auth0 dashboard application section.
Callback URL Configuration:
A callback URL is required for redirecting the user after the authentication process from the auth0.
The callback URL needs to be added to the allowed callback section of the auth0 application dashboard. if this field is blank then the user will not be able to log in to the app and the user will get the error message.
Logout URLs configuration:
A logout URL is a URL that is required in your application when the user logout from the Auth0 server it will return to the specific URL that we will set up in the logout section of the Auth0 application dashboard.
The Allowed Logout URL section is defined in the application settings.
If this field is blank, users will not be able to log out of the application and will get an error message.
Flask- Auth0 implementation
We will use the following dependencies for auth0 implementation with flask and will install these dependencies in our requirement.txt file.
requirement.txt Flask Python-dotenv Requests Flask-oauthlib Six 1.10.0
- Create a virtual environment for the python project so it will not conflict with any other project.
virtualenv --system-site-packages -p python3 user_env
- Activate this newly created virtual environment
source user_env/bin/activate
- Install the requirements in the virtual environment
pip install - r requirement.txt
Authlib library initialization:
For the initialization of the authlib library, we will create a file and we will add all the generated client keys and the credentials in this file.
Application.py from functools import wraps import json from os import environ as env from werkzeug.exceptions import HTTPException from dotenv import load_dotenv, find_dotenv from flask import Flask from flask import jsonify from flask import redirect from flask import render_template from flask import session from flask import url_for from authlib.integrations.flask_client import OAuth from six.moves.urllib.parse import urlencode application = Flask(__name__) oauth = OAuth(application) auth0 = oauth.register( 'auth0', client_id='CLIENT_ID', client_secret='CLIENT_SECRET', api_base_url='YOUR_DOMAIN', access_token_url='YOUR_DOMAIN/’', authorize_url='https://YOUR_DOMAIN/authorize', client_kwargs={ 'scope': 'openid email profile read:users read:user_idp_tokens read:current_user_metadata create:current_user_metadatal', }, )
Adding the Callback in the Application:
This snippet will be used to exchange the data that Auth0 sends to the callback URL for an Access Token and an ID Token.
This token will be used to call the /userinfo endpoint to get the user profile information like first name, last name, email etc.. After the user information is fetched,we will store these details in the flask session
# Here we're using the /callback route. @app.route('/callback') def callback_handler(): # Handles response from auth0 auth0.authorize_access_token() resp = auth0.get('userinfo') user_info = resp.json() # Store the user information in the flask session. session['jwt_payload'] = user_info session['profile'] = { 'user_id': userinfo['sub'], 'name': userinfo['name'], } return redirect('/profile')
Handle Authentication
For the authentication process, we need to create a /userlogin route that will be used for redirecting users to the login prompt. We need to update the callback_url in this following snippet.
# /application.py @app.route('/loginuser') def user_login(): return auth0.authorize_redirect(redirect_uri='CALLBACK_URL')
Create a login.html file in the template folder and add the /userlogin route in the HTML snippet.
<div class="user-login auth0"> <img src="https://i.cloudup.com/StzWWrY34s.png" /> <h3>Auth0 demo</h3> <p>welcome to the Auth0</p> <a class="btn btn-primary btn-lg btn-login btn-block" href="/userlogin">Log In</a> </div>
Code snippet for displaying the user information:
@app.route('/profile') @requires_auth def profile(): return render_template('profile.html', userinfo=session['profile'], userinfo_pretty=json.dumps(session['jwt_payload'], indent=3))
We will create a profile.html file inside the /template folder for displaying the user information
<div class="user-logged-in auth0 userdetails"> <h2 id="img"><img src="//cdn.auth0.com/samples/auth0_logo.png" /></h2> <img class="avatar" src="{{userinfo['picture']}}"/> <h3>Welcome {{userinfo['name']}}</h3> <a class="btn btn-primary btn-lg btn-logout btn-block" href="/userLogout">Logout</a> </div>
Logout:
For auth0 logout functionality we need to clear the user data from the session and redirect the user to the auth0 logout endpoint that we have already defined in the application setting.
# /application.py @app.route('/logout') def user_logout(): session.clear() #Redirecting user to logout endpoint params = {'returnTo': url_for('home', _external=True), 'client_id': 'CLIENT_ID'} return redirect(auth0.api_base_url + '/v2/logout?' + urlencode(params))