Skip to content

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
依赖包说明
FlaskPython Web 框架
Authlib功能全面的 OAuth/OIDC 库,支持 OIDC 自动发现和令牌管理
requestsHTTP 客户端库,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_idredirect_uriscopestatenonce),并将用户重定向到 Code Bird Cloud 的登录页面。Authlib 自动处理 statenonce 的生成与验证。

回调路由 /callback

oauth.codebird.authorize_access_token() 完成以下操作:

  1. 从回调 URL 中提取授权码
  2. 验证 state 参数
  3. 用授权码向令牌端点换取令牌
  4. 验证 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

相关文档

Released under the MIT License.