Python Flask 集成教程
本教程介绍如何使用 Python + Flask + Authlib 通过 Authorization Code Flow 集成 Code Bird Cloud 进行用户认证。
前置条件
- Python 3.10 或更高版本
- pip 包管理器
- 已在 Code Bird Cloud 管理后台创建 Traditional 类型的应用,并获取 Client ID 和 Client Secret
- 已配置 Redirect URI 为
http://localhost:5000/callback
安装依赖
bash
pip install Flask Authlib requests| 依赖包 | 说明 |
|---|---|
Flask | Python Web 框架 |
Authlib | 功能全面的 OAuth/OIDC 库,支持 OIDC 自动发现和令牌管理 |
requests | HTTP 客户端库,Authlib 依赖 |
完整代码示例
python
import os
from flask import Flask, redirect, session, url_for, jsonify
from authlib.integrations.flask_client import OAuth
app = Flask(__name__)
app.secret_key = os.urandom(24)
ISSUER = "https://your-domain.com"
CLIENT_ID = os.environ["CLIENT_ID"]
CLIENT_SECRET = os.environ["CLIENT_SECRET"]
oauth = OAuth(app)
oauth.register(
name="codebird",
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
server_metadata_url=f"{ISSUER}/.well-known/openid-configuration",
client_kwargs={
"scope": "openid profile email offline_access",
},
)
@app.route("/login")
def login():
"""Redirect the user to Code Bird Cloud's authorization endpoint."""
redirect_uri = url_for("callback", _external=True)
return oauth.codebird.authorize_redirect(redirect_uri)
@app.route("/callback")
def callback():
"""Handle the authorization callback and exchange the code for tokens."""
token = oauth.codebird.authorize_access_token()
# The token dict contains access_token, id_token, refresh_token, etc.
access_token = token.get("access_token")
refresh_token = token.get("refresh_token")
# Fetch user info using the access token
user_info = oauth.codebird.userinfo()
# Store tokens in session (use a secure store in production)
session["access_token"] = access_token
session["refresh_token"] = refresh_token
session["user"] = dict(user_info)
return jsonify({
"message": "Login successful",
"user": dict(user_info),
})
@app.route("/profile")
def profile():
"""Return the current user's profile from the session."""
user = session.get("user")
if not user:
return redirect(url_for("login"))
return jsonify(user)
@app.route("/refresh")
def refresh():
"""Refresh the access token using the stored refresh token."""
stored_refresh_token = session.get("refresh_token")
if not stored_refresh_token:
return jsonify({"error": "No refresh token available"}), 400
# Use Authlib's token refresh mechanism
new_token = oauth.codebird.fetch_access_token(
grant_type="refresh_token",
refresh_token=stored_refresh_token,
)
session["access_token"] = new_token.get("access_token")
if new_token.get("refresh_token"):
session["refresh_token"] = new_token["refresh_token"]
return jsonify({"message": "Token refreshed successfully"})
@app.route("/logout")
def logout():
"""Clear the session and redirect to the home page."""
session.clear()
return redirect("/")
@app.route("/")
def home():
"""Home page with login link."""
user = session.get("user")
if user:
return jsonify({
"message": f"Welcome, {user.get('name', 'User')}",
"links": {
"profile": "/profile",
"refresh": "/refresh",
"logout": "/logout",
},
})
return jsonify({
"message": "Code Bird Cloud Flask Demo",
"links": {"login": "/login"},
})
if __name__ == "__main__":
app.run(debug=True, port=5000)代码说明
OAuth 客户端注册
oauth.register() 配置 Code Bird Cloud 作为 OIDC Provider。server_metadata_url 指向 OIDC 发现端点,Authlib 会自动获取授权端点、令牌端点等配置信息。
登录路由 /login
oauth.codebird.authorize_redirect() 会自动构建授权 URL(包含 client_id、redirect_uri、scope、state、nonce),并将用户重定向到 Code Bird Cloud 的登录页面。Authlib 自动处理 state 和 nonce 的生成与验证。
回调路由 /callback
oauth.codebird.authorize_access_token() 完成以下操作:
- 从回调 URL 中提取授权码
- 验证
state参数 - 用授权码向令牌端点换取令牌
- 验证 ID Token 签名和 Claims
oauth.codebird.userinfo() 使用 Access Token 调用 UserInfo 端点获取用户信息。
令牌刷新路由 /refresh
使用存储的 Refresh Token 获取新的 Access Token。需要在初始授权请求的 scope 中包含 offline_access 才会返回 Refresh Token。
登出路由 /logout
清除本地 Session。如需同时结束 Code Bird Cloud 端的会话,可以重定向到 /oidc/end-session 端点。
运行
bash
# 设置环境变量
export CLIENT_ID="your_client_id"
export CLIENT_SECRET="your_client_secret"
# 启动服务
python app.py访问 http://localhost:5000/login 开始登录流程。
生产环境注意事项
- 将
app.secret_key替换为固定的密钥,使用环境变量管理 - 使用 Redis 或数据库存储 Session,不要使用 Flask 默认的客户端 Session 存储令牌
- 配置 HTTPS
- 关闭
debug=True
相关文档
- Authorization Code Flow 参考 -- 流程详解和参数说明
- 集成概览 -- 所有集成方式的总览
