You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Flask网站中实现类似Reddit的Google账号登录弹窗

Flask实现Reddit风格Google账号弹窗登录方案

1. 前置准备

  • 先在Google Cloud控制台创建OAuth 2.0客户端ID,授权重定向URI填写你站点的回调地址,比如https://你的域名/auth/google/callback
  • 安装所需依赖:
    pip install flask flask-login google-auth google-auth-oauthlib google-auth-httplib2

2. 后端Flask核心代码

from flask import Flask, redirect, request, url_for, render_template_string, session
from flask_login import LoginManager, UserMixin, login_user
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import Flow
from googleapiclient.discovery import build

app = Flask(__name__)
app.secret_key = "你的自定义加密密钥"
login_manager = LoginManager()
login_manager.init_app(app)

# 替换为你自己的Google OAuth客户端配置
GOOGLE_CLIENT_CONFIG = {
    "web": {
        "client_id": "你的Google客户端ID",
        "client_secret": "你的Google客户端密钥",
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "redirect_uris": ["https://你的域名/auth/google/callback"]
    }
}
SCOPES = ["openid", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"]

# 简易用户模型,可替换为你自己的数据库模型
class User(UserMixin):
    def __init__(self, user_id, email, name):
        self.id = user_id
        self.email = email
        self.name = name
    # 可自行补充从数据库查询/创建用户的静态方法

@login_manager.user_loader
def load_user(user_id):
    # 这里替换为从数据库查询用户的逻辑
    return User(user_id, "test@example.com", "测试用户")

# Google登录入口
@app.route("/auth/google")
def google_login():
    flow = Flow.from_client_config(GOOGLE_CLIENT_CONFIG, scopes=SCOPES)
    flow.redirect_uri = url_for("google_callback", _external=True)
    authorization_url, state = flow.authorization_url(access_type="offline", include_granted_scopes="true")
    # 把state存入session用于后续校验
    session["state"] = state
    return redirect(authorization_url)

# Google登录回调
@app.route("/auth/google/callback")
def google_callback():
    state = session.get("state")
    flow = Flow.from_client_config(GOOGLE_CLIENT_CONFIG, scopes=SCOPES, state=state)
    flow.redirect_uri = url_for("google_callback", _external=True)
    flow.fetch_token(authorization_response=request.url)
    
    # 获取用户信息
    credentials = flow.credentials
    user_info_service = build("oauth2", "v2", credentials=credentials)
    user_info = user_info_service.userinfo().get().execute()
    
    # 这里写你自己的用户处理逻辑:判断用户是否存在,不存在则创建,然后登录
    user = User(user_id=user_info["id"], email=user_info["email"], name=user_info["name"])
    login_user(user)
    
    # 返回关闭弹窗+父页面刷新的脚本,实现Reddit同款弹窗关闭效果
    return """
    <script>
        window.opener.location.reload();
        window.close();
    </script>
    """

# 首页,包含登录按钮
@app.route("/")
def index():
    return render_template_string("""
    <!-- 登录按钮样式参考Reddit设计 -->
    <button id="google-login-btn" style="padding: 10px 20px; border: 1px solid #dadce0; border-radius: 20px; background: white; cursor: pointer; display: flex; align-items: center; gap: 10px;">
        <svg width="18" height="18" viewBox="0 0 18 18">
            <!-- 这里填入Google logo的svg路径 -->
        </svg>
        使用Google账号登录
    </button>

    <script>
        document.getElementById("google-login-btn").addEventListener("click", () => {
            // 弹窗参数和Reddit保持一致:固定宽高,居中显示
            const width = 500;
            const height = 600;
            const left = (window.screen.width / 2) - (width / 2);
            const top = (window.screen.height / 2) - (height / 2);
            window.open(
                "/auth/google",
                "google_login",
                `width=${width},height=${height},top=${top},left=${left},resizable=yes,scrollbars=yes`
            );
        });
    </script>
    """)

if __name__ == "__main__":
    app.run(debug=True)

3. 注意事项

  • 生产环境不要硬编码客户端密钥、加密密钥等敏感信息,建议通过环境变量读取
  • 必须校验回调请求的state参数,防止CSRF攻击
  • 生产环境站点必须使用HTTPS,Google OAuth不允许HTTP地址作为回调地址(本地调试除外)
  • 可以自行调整按钮的样式、弹窗的宽高参数,和Reddit的登录效果完全对齐

内容的提问来源于stack exchange,提问作者Nikhil Tank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 17:54:03