Python
Sign users in to a Flask or Django app with Authlib, using discovery and PKCE with no client secret.
Authlib supports OpenID Connect discovery and PKCE in Flask, Django, Starlette and FastAPI. This example uses Flask.
Install
pip install flask authlib requests
The app
from flask import Flask, redirect, session, url_for
from authlib.integrations.flask_client import OAuth
app = Flask(__name__)
app.secret_key = "change-me"
oauth = OAuth(app)
oauth.register(
"gatekeep",
client_id="acme-notes",
server_metadata_url="https://acme.gatekeepauth.com/.well-known/openid-configuration",
client_kwargs={
"scope": "openid email",
"code_challenge_method": "S256", # PKCE
"token_endpoint_auth_method": "none", # no client secret
},
)
@app.route("/login")
def login():
return oauth.gatekeep.authorize_redirect(url_for("callback", _external=True))
@app.route("/auth/callback")
def callback():
token = oauth.gatekeep.authorize_access_token() # checks state, nonce and the ID token
user = token["userinfo"]
session["user"] = {"id": user["sub"], "email": user["email"]}
return redirect("/")
@app.route("/")
def home():
user = session.get("user")
return f"Hello {user['email']}" if user else '<a href="/login">Sign in</a>'
Register http://localhost:5000/auth/callback (and your production URL) as redirect URIs.
ID tokens are signed with EdDSA (Ed25519). Authlib verifies them with the
cryptography package, which pip install authlib brings in. If verification fails with an unsupported-algorithm error, upgrade Authlib.