Iniciar sesión con UTILIA en Flask
Añade el botón «Iniciar sesión con UTILIA» a una aplicación Flask con Authlib, que descubre la configuración de UTILIA OS y verifica el id_token por ti.
Actualizado el . 2 min de lectura
Con Authlib, UTILIA OS funciona como cualquier proveedor OpenID Connect: lee su documento de descubrimiento, hace PKCE, canjea el código y verifica el id_token. Solo tienes que registrar el proveedor y escribir dos rutas.
Antes de empezar
- Python 3.9 o superior.
- Activa OAuth en tu aplicación externa, con el tipo Con servidor propio (recomendado), como explica Activar OAuth en tu aplicación.
- Añade como dirección de vuelta
http://localhost:5000/callbackpara desarrollo y la de producción con tu dominio.
Instala las dependencias
Bashpip install flask authlib requestsRegistra el proveedor
Pythonimport os from authlib.integrations.flask_client import OAuth from flask import Flask app = Flask(__name__) app.secret_key = os.environ["FLASK_SECRET_KEY"] oauth = OAuth(app) oauth.register( name="utilia", client_id=os.environ["UTILIA_CLIENT_ID"], client_secret=os.environ["UTILIA_CLIENT_SECRET"], server_metadata_url="https://os.utilia.ai/.well-known/openid-configuration", client_kwargs={ "scope": "openid profile email", # UTILIA OS exige PKCE con S256: sin esta línea, Authlib no lo envía. "code_challenge_method": "S256", }, )No quites code_challenge_method
UTILIA OS rechaza cualquier autorización sin
code_challenge, y Authlib solo genera PKCE si declarascode_challenge_methodenclient_kwargs.Crea la ruta de inicio de sesión
Pythonfrom flask import url_for @app.route("/login") def login(): redirect_uri = url_for("callback", _external=True) return oauth.utilia.authorize_redirect(redirect_uri)Lleva a la persona a la pantalla de autorización de UTILIA OS. Authlib genera y guarda en la sesión de Flask el
state, elnoncey elcode_verifier.Crea la ruta de vuelta
Pythonfrom flask import redirect, session @app.route("/callback") def callback(): token = oauth.utilia.authorize_access_token() userinfo = token["userinfo"] # claims del id_token, ya verificado session["user"] = { "sub": userinfo["sub"], "name": userinfo.get("name"), "email": userinfo.get("email"), "picture": userinfo.get("picture"), } return redirect("/")authorize_access_token()comprueba elstate, canjea el código y verifica la firma y los datos delid_token. Guardasubcomo identificador de la persona: no cambia.
Variables de entorno
export UTILIA_CLIENT_ID=utilia_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export UTILIA_CLIENT_SECRET=tu_clave_secreta
export FLASK_SECRET_KEY=una_clave_aleatoria_largaNunca escribas la clave secreta en el código fuente.
Ejemplo completo
import os
from authlib.integrations.flask_client import OAuth
from flask import Flask, redirect, session, url_for
from markupsafe import escape
app = Flask(__name__)
app.secret_key = os.environ["FLASK_SECRET_KEY"]
oauth = OAuth(app)
oauth.register(
name="utilia",
client_id=os.environ["UTILIA_CLIENT_ID"],
client_secret=os.environ["UTILIA_CLIENT_SECRET"],
server_metadata_url="https://os.utilia.ai/.well-known/openid-configuration",
client_kwargs={
"scope": "openid profile email",
"code_challenge_method": "S256",
},
)
@app.route("/")
def index():
user = session.get("user")
if not user:
return '<a href="/login">Iniciar sesión con UTILIA</a>'
return f"<h1>Hola, {escape(user['name'])}</h1><a href='/logout'>Cerrar sesión</a>"
@app.route("/login")
def login():
return oauth.utilia.authorize_redirect(url_for("callback", _external=True))
@app.route("/callback")
def callback():
token = oauth.utilia.authorize_access_token()
userinfo = token["userinfo"]
session["user"] = {
"sub": userinfo["sub"],
"name": userinfo.get("name"),
"email": userinfo.get("email"),
}
return redirect("/")
@app.route("/logout")
def logout():
session.pop("user", None)
return redirect("/")
if __name__ == "__main__":
app.run(debug=True)Si solo usas UTILIA OS para identificar a la persona, no necesitas guardar los tokens: basta con borrar session["user"] al cerrar sesión. Si los guardas para llamar a sus servidores MCP, hazlo en tu servidor (la cookie de sesión de Flask va firmada, pero no cifrada) y revócalos al cerrar sesión con POST /api/oauth/revoke, como explica Cierre de sesión desde tu aplicación.
Para el estilo del botón, mira Botones y marca. Si algo falla, Problemas frecuentes con OAuth.