Install & Compatibility
Where this runs
tested against v1.3.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.594s · 23.7MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.6s · import 0.554s · 24MB
22MB installed
● package 22MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
OpenID
✓ from flask_openid import OpenID
This quickstart demonstrates a basic Flask application using Flask-OpenID for user authentication. It includes routes for login, logout, and handling OpenID responses, creating a temporary file-based store for OpenID data. Ensure to set the `FLASK_SECRET_KEY` environment variable in production.
import os
from flask import Flask, render_template, session, request, redirect, url_for
from flask_openid import OpenID
app = Flask(__name__)
app.config.update(
SECRET_KEY=os.environ.get('FLASK_SECRET_KEY', 'a_very_secret_key_for_dev'), # CHANGE THIS FOR PROD
OPENID_FS_STORE=os.path.join(os.path.dirname(__file__), 'tmp', 'openid_store')
)
oid = OpenID(app)
@app.route('/')
@oid.loginhandler
def index():
if oid.fetch_user():
return f'Hello, {session["name"]}! <p><a href="{url_for("logout")}">Logout</a></p>'
return render_template('login.html', next=oid.get_next_url(), error=oid.fetch_error())
@app.route('/login', methods=['GET', 'POST'])
@oid.loginhandler
def login():
if oid.fetch_user():
return redirect(oid.get_next_url())
if request.method == 'POST':
openid = request.form.get('openid_identifier')
if openid:
return oid.try_login(openid, ask_for=['email', 'nickname'],
ask_for_optional=['fullname'])
return render_template('login.html', next=oid.get_next_url(),
error=oid.fetch_error())
@app.route('/logout')
def logout():
oid.logout()
return redirect(oid.get_next_url())
@oid.after_login
def create_or_login(resp):
session['openid'] = resp.identity_url
session['name'] = resp.fullname or resp.nickname or resp.identity_url
return redirect(oid.get_next_url())
if __name__ == '__main__':
# Create necessary directories and a minimal login.html for the quickstart to run
os.makedirs(app.config['OPENID_FS_STORE'], exist_ok=True)
os.makedirs('templates', exist_ok=True)
with open('templates/login.html', 'w') as f:
f.write('''
<!doctype html>
<html>
<head><title>Login</title></head>
<body>
<h1>Login with OpenID</h1>
{% if error %}<p style="color: red;">Error: {{ error }}</p>{% endif %}
<form action="{{ url_for('login') }}" method="post">
<dl>
<dt>OpenID:</dt>
<dd><input type="text" name="openid_identifier" value="" placeholder="e.g. https://openid.aol.com/yourusername" /></dd>
<dd><input type="submit" value="Login" /></dd>
</dl>
</form>
<p><a href="{{ url_for('logout') }}">Logout</a></p>
</body>
</html>
''')
app.run(debug=True)
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'flask_openid'
The `flask-openid` library or its underlying dependencies (like `python-openid`) are not installed, not installed in the active virtual environment, or there's a capitalization mismatch in the import statement.
fixEnsure the package is installed using pip: `pip install Flask-OpenID`. Also, verify the import statement uses `from flask_openid import OpenID` (lowercase `flask_openid`).
ImportError: cannot import name 'TimedJSONWebSignatureSerializer' from 'itsdangerous'
This error occurs due to an incompatibility between `flask-openid` (or its dependency `Flask-AppBuilder` in some contexts) and newer versions of the `itsdangerous` library. `TimedJSONWebSignatureSerializer` was removed or renamed in recent `itsdangerous` versions.
fixPin the `itsdangerous` dependency to an older, compatible version. A common fix is `pip install 'itsdangerous<2.0.0'` or `pip install 'itsdangerous==1.1.0'`.
OpenID realm and return_to parameters point to localhost instead of proxy URL
When `flask-openid` is deployed behind a reverse proxy (like Nginx or Apache), it might generate OpenID `realm` and `return_to` URLs based on the internal Flask application's address (e.g., `127.0.0.1:5000`) instead of the publicly accessible proxy URL, leading to incorrect redirects and authentication failures.
fixConfigure your reverse proxy to correctly pass `Host`, `X-Forwarded-For`, and `X-Forwarded-Proto` headers to the Flask application. You might also need to use `Werkzeug`'s `ProxyFix` middleware in your Flask application. Example for Nginx: `proxy_set_header Host $host;` and in Flask: `app.wsgi_app = ProxyFix(app.wsgi_app)`.
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.
This error typically arises when using `flask-openid` with Python 3, as the underlying `python-openid` library (especially older versions) had compatibility issues with Python 3's string handling.
fixEnsure you are using a Python 3 compatible version of `python-openid`. Although `flask-openid` is in maintenance mode, upgrading `python-openid` might resolve some issues. If the issue persists, consider migrating to a more modern authentication library like `Flask-OIDC` or direct OAuth2/OpenID Connect implementations, as OpenID 1.x/2.x itself has Python 3 compatibility challenges.
Upgrade
Version history
1.3.1latest on PyPI · released May 26, 2024
Audit
Dependencies
python-openidrequiredCore library for OpenID 1.x/2.x protocol handling.