This tutorial shows how to use PlusAuth with Python and Flask. If you do not have a PlusAuth account, register from here .
This tutorial follows plusauth-python-starter sample project on Github. You can download and follow the tutorial via the sample project.
After you sign up or log in to PlusAuth, you need to create a client to get the necessary configuration keys in the dashboard. Go to Clients and create a client with the type of Regular Web Application
You will need your Client Id
and Client Secret
for interacting with PlusAuth. You can retrieve them from the created client's details.
When PlusAuth authenticates a user, it needs a URI to redirect back. That URI must be in your client's Redirect URI
list. If your application uses a redirect URI that is not white-listed in your PlusAuth Client, you will receive an error.
The same thing applies to the logout URIs. After the user logs out, you need a URI to be redirected.
If you are following the sample project, the Redirect URL you need to add to the Redirect URIs field is http://localhost:3000/login/callback
and the Logout URL you need to add to the Post Logout Redirect URIs field is http://localhost:3000/logout
.
Create a Python application or download the sample project from the link on the top of the page.
Create the .env
file in the root of your app and add your PlusAuth variables and values to it.
AUTH_URL =https://{YOUR-TENANT-NAME}.plusauth.com
CLIENT_ID ={YOUR-CLIENT-ID}
CLIENT_SECRET ={YOUR-CLIENT-SECRET}
Do not put the .env
file into source control. Otherwise, your history will contain references to your client's secret. If you are using git, create a .gitignore
file (or edit your existing one, if you have one already) and add .env
to it. The .gitignore
file tells source control to ignore the files (or file patterns) you list. Be careful to add .env
to your .gitignore
file and commit that change before you add your .env
If you are following the sample project, rename .env.example
to .env
and replace the values accordingly.
To get started, install the following requirements.
Install the requirements using pip3
.
pip3 install -r requirements.txt
To enable authentication with PlusAuth, create index.py
at the root of your project. Then configure flask_pyoidc
and create an auth
object.
from os import environ as env
from flask import Flask, jsonify, render_template, redirect, session
from flask_pyoidc import OIDCAuthentication
from flask_pyoidc.provider_configuration import ProviderConfiguration, ClientMetadata
from flask_pyoidc.user_session import UserSession
from dotenv import load_dotenv
load_dotenv() # Load environment variables
OIDC_REDIRECT_URI = 'http://localhost:3000/login/callback' ,
SECRET_KEY = 'SessionSecretKey' # flask_pyoidc extension relies on Flask sessions, which requires SECRET_KEY
client_metadata = ClientMetadata(
client_id = env.get( "CLIENT_ID" ),
client_secret = env.get( "CLIENT_SECRET" ))
auth_params = { 'scope' : [ 'openid' , 'profile' , 'email' ]}
config = ProviderConfiguration(
issuer = env.get( "AUTH_URL" ),
client_metadata = client_metadata,
auth_request_params = auth_params)
auth = OIDCAuthentication({ 'default' : config}, app)
You may have noticed that the values defined in Configure Client section are used here. If you have used different values make sure to update this file accordingly.
Add routes to your application to serve HTML.
@auth.oidc_auth ( 'default' )
def error (error = None , error_description = None ):
return jsonify({ 'error' : error, 'message' : error_description})
user_session = UserSession(session, 'default' )
return render_template( 'index.html' , user = user_session.userinfo)
@auth.oidc_auth ( 'default' )
user_session = UserSession(session, 'default' )
return render_template( 'profile.html' , user = user_session.userinfo)
if __name__ == '__main__' :
app.run( debug = True , port = 3000 )
We defined the routes of our views above. @auth.oidc_auth
annotation in the metadata will ensure those routes are accessible only by authenticated users.
Create main.html
under the templates
folder.
<!-- templates/main.html -->
content = "width=device-width, initial-scale=1, shrink-to-fit=no"
< title >Plusauth Starter Template</ title >
href = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity = "sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
< nav class = "navbar navbar-expand-md navbar-dark bg-dark fixed-top" >
< a class = "navbar-brand" href = "/" >Plusauth Starter</ a >
< div class = "collapse navbar-collapse" id = "navbarsExampleDefault" >
< ul class = "navbar-nav mr-auto" ></ ul >
< li class = "nav-item navbar-nav" >
< a class = "nav-link" href = "/profile" >
Logged in as: {{ user.username }}
< a class = "nav-link" href = "/logout" > Logout </ a >
< li class = "nav-item navbar-nav" >
< a class = "nav-link" href = "/login" > Login </ a >
< main role = "main" class = "container" >{% block content %}{% endblock %}</ main >
Create index.html
under templates
folder.
<!-- templates/index.html -->
{% extends 'main.html' %} {% block content %}
< h1 class = "display-3" >Hello, world!</ h1 >
This is a template for a simple login/register system. It includes a
simple OpenID Connect Authorization Code Flow. To view Profile page please
< a class = "btn btn-success btn-lg" href = "/profile" role = "button"
< a class = "btn btn-primary btn-lg" href = "/login" role = "button"
>Login/Register » </ a
Login button redirects to /login/callback
that is provided by flask_pyoidc
. It will redirect to the PlusAuth login page. After successful login, PlusAuth redirects back to the same endpoint to create and store the session.
Create profile.html
under templates
folder.
<!-- templates/profile.html -->
{% extends 'main.html' %} {% block content %}
< h3 >Welcome {{ user.email }}!</ h3 >
< pre >{{ user|tojson(indent=2) }}</ pre >
That's it. Start your app and point your browser to http://localhost:3000 . Follow the Log In link to log in or sign up to your PlusAuth tenant. Upon successful login or signup, you should be redirected back to the application.