Avnology ID
SDKsPython SDKGuides

Flask Integration

Protect Flask endpoints with Avnology ID authentication and authorization.

Flask Integration

Setup

pip install avnology-id flask

Client initialization

# app.py
from flask import Flask, g, request, jsonify
from avnology_id import AvnologyId

app = Flask(__name__)

client = AvnologyId(
    base_url="https://api.id.avnology.com",
    client_id=app.config["AVNOLOGY_CLIENT_ID"],
    client_secret=app.config["AVNOLOGY_CLIENT_SECRET"],
)

Authentication decorator

from functools import wraps

def require_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth_header = request.headers.get("Authorization", "")
        if not auth_header.startswith("Bearer "):
            return jsonify({"error": "missing_token"}), 401

        token = auth_header.removeprefix("Bearer ")
        result = client.oauth.introspect_token(token=token)

        if not result.active:
            return jsonify({"error": "invalid_token"}), 401

        g.user_id = result.sub
        g.scopes = result.scope.split()
        g.org_id = result.org_id
        return f(*args, **kwargs)

    return decorated

@app.route("/api/profile")
@require_auth
def get_profile():
    user = client.admin.get_user(user_id=g.user_id)
    return jsonify({"email": user.email, "name": user.name})

OAuth login flow

from flask import session, redirect

@app.route("/login")
def login():
    result = client.oauth.build_authorization_url(
        scopes=["openid", "profile", "email"],
        redirect_uri="https://myapp.com/callback",
    )
    session["code_verifier"] = result.code_verifier
    session["oauth_state"] = result.state
    return redirect(result.url)

@app.route("/callback")
def callback():
    if request.args.get("state") != session.get("oauth_state"):
        return "State mismatch", 400

    tokens = client.oauth.exchange_code(
        code=request.args["code"],
        code_verifier=session.pop("code_verifier"),
        redirect_uri="https://myapp.com/callback",
    )

    session["access_token"] = tokens.access_token
    return redirect("/dashboard")

Webhook handler

from avnology_id.webhook import verify_signature

@app.route("/webhooks/avnology", methods=["POST"])
def handle_webhook():
    payload = request.get_data()
    signature = request.headers.get("X-Avnology-Signature", "")

    if not verify_signature(payload, signature, WEBHOOK_SECRET):
        return jsonify({"error": "invalid_signature"}), 401

    event = request.get_json()
    # Process event...

    return "", 200

See also

On this page