Flask-OpenID

1.3.1 · maintenance · verified Fri Apr 10

Flask-OpenID is a Flask extension that provides OpenID 1.x and 2.x authentication support for web applications. The current version is 1.3.1, released in 2021. It is in maintenance mode, primarily for existing applications, as the OpenID Connect standard has largely superseded OpenID 1/2 for new development.

Warnings

Install

Imports

Quickstart

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)

view raw JSON →