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

Google Cloud Run上Python会话自动登出:如何保持用户登录?

问题根源分析

你的Flask应用存在两个核心问题导致会话无法持久:

  1. 每次启动用os.urandom(12)生成随机secret_key,而Google Cloud Run是无状态容器服务,实例会随流量扩缩容、自动重启,不同实例的密钥不一致,已签名的会话cookie在新实例上无法验证,用户被迫登出。
  2. 未配置会话持久化参数,Flask默认的会话cookie有效期较短,且未开启永久会话支持。

具体解决步骤

1. 固定并安全存储Secret Key

不能每次启动生成随机密钥,需使用一个固定的、全局共享的安全密钥:

  • 本地生成足够长的随机密钥:执行以下Python命令生成64位随机字符串
    python -c "import secrets; print(secrets.token_hex(32))"
    
  • 将密钥存储到Google Cloud Secret Manager(推荐),或直接作为Cloud Run的环境变量。
  • 修改main.py中的密钥配置,从环境变量读取:
    # 替换原有的app.secret_key = os.urandom(12)
    app.secret_key = os.environ.get('FLASK_SECRET_KEY')
    
  • 部署Cloud Run时,添加环境变量FLASK_SECRET_KEY,值为你生成的固定密钥(使用Secret Manager时,需配置服务账号权限并挂载密钥为环境变量)。

2. 配置会话持久化与安全参数

在main.py中添加会话生命周期及安全配置:

from datetime import timedelta

# 配置会话有效期为7天(可按需调整)
app.permanent_session_lifetime = timedelta(days=7)

# 开启HTTPS环境下的安全cookie配置
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'

# 修改登录逻辑,开启永久会话
@app.route('/', methods=['GET', 'POST'])
def __index():
    # 处理登录请求(仅POST方法)
    if request.method == 'POST' and not session.get('logged_in'):
        inp_username = request.form.get('inp_username')
        inp_password = request.form.get('inp_password')
        
        if inp_username == "hello" and inp_password == "world":
            session['logged_in'] = True
            # 标记会话为永久,触发permanent_session_lifetime配置
            session.permanent = True

    # 根据登录状态返回内容
    if session.get('logged_in'):
        return "Welcome to the website", 200
    else:
        # 返回登录表单(原代码直接返回Access denied会导致用户无法登录)
        return '''
            <form method="POST">
                Username: <input type="text" name="inp_username"><br>
                Password: <input type="password" name="inp_password"><br>
                <input type="submit" value="Login">
            </form>
        ''', 200

3. 修复代码潜在问题

原代码中未判断请求方法,GET请求时访问request.form会抛出KeyError,上述代码已修复该问题,确保仅在POST请求时处理登录逻辑。

4. 重新部署验证

重新构建Docker镜像并部署到Cloud Run,确保所有实例共享同一个FLASK_SECRET_KEY,测试登录后,即使实例重启或扩缩容,用户也不会被强制登出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:42:31