【问题标题】:Why does the session cookie work when serving from a domain but not when using an IP?为什么会话 cookie 在从域提供服务时有效,但在使用 IP 时无效?
【发布时间】:2015-01-30 23:17:54
【问题描述】:

我有一个 Flask 应用程序,其会话在我的本地开发机器上运行良好。但是,当我尝试在 Amazon 服务器上部署它时,会话似乎不起作用。

更具体地说,未设置会话 cookie。但是,我可以设置普通的 cookie。我确保我有一个静态安全密钥,因为其他人表示这可能是一个问题。唯一的区别在于服务器的设置方式。在开发过程中,我使用

app.run()

在本地运行。部署时,我使用

app.config['SERVER_NAME'] = '12.34.56.78'  # <-- insert a "real" IP
app.run(host='0.0.0.0', port=80)

我怀疑问题可能出在上面,但不完全确定。

会话确实似乎在 Firefox 上有效,但在 Chrome 上无效。

以下小应用程序演示了该问题,底部有配置差异:

from flask import Flask, make_response, request, session

app = Flask(__name__)
app.secret_key = 'secretKey'

# this is to verify that cookies can be set
@app.route('/setcookie')
def set_cookie():
    response = make_response('Cookie set')
    response.set_cookie('cookie name', 'cookie value')
    return response

@app.route('/getcookie')
def get_cookie():
    if 'cookie name' in request.cookies:
        return 'Cookie found. Its value is %s.' % request.cookies['cookie name']
    else:
       return 'Cookie not found'

# this is to check if sessions work
@app.route('/setsession')
def set_session():
    session['session name'] = 'session value'
    return 'Session set'

@app.route('/getsession')
def get_session():
    if 'session name' in session:
        return 'Session value is %s.' % session['session name']
    else:
        return 'Session value not found'

if __name__ == '__main__':
    app.debug = True

    # windows, local development
    #app.run()  

    # Ubuntu
    app.config['SERVER_NAME'] = '12.34.56.78'  # <-- insert a "real" IP
    app.run(host='0.0.0.0', port=80)

【问题讨论】:

    标签: python session cookies flask


    【解决方案1】:

    这是 Chrome 中的“错误”,而不是您的应用程序的问题。 (如果其他浏览器更改其政策,也可能会受到影响。)

    RFC 2109 描述了 cookie 的处理方式,似乎表明 cookie 域必须是带有 TLD(.com、.net 等)的 FQDN,或者是完全匹配的 IP 地址。 original Netscape cookie spec 根本没有提到 IP 地址。

    Chrome 开发人员决定比其他浏览器更严格地规定他们接受 cookie 域的值。虽然在某一时刻 they corrected a bug 阻止了 IP 地址上的 cookie,但 they have apparently backpedaled 从那时起不允许非 FQDN 域(包括本地主机)或 IP 地址上的 cookie。他们已经声明他们不会修复这个问题,因为他们不认为这是一个错误。

    “正常”cookie 工作但会话 cookie 不工作的原因是您没有为“正常”cookie 设置域(这是一个可选参数),但 Flask 自动将会话 cookie 的域设置为SERVER_NAME。 Chrome(和其他人)接受没有域的 cookie 并将它们自动设置为响应的域,因此观察到的行为差异。如果您将域设置为 IP 地址,您可以观察正常 cookie 失败。

    在开发过程中,您可以通过在 localhost 上运行应用程序而不是让它默认为 127.0.0.1 来解决这个问题。 Flask has a workaround 如果服务器名称是 localhost,则不会发送会话 cookie 的域。 app.run('localhost')

    在生产中,没有任何真正的解决方案。您可以在域而不是 IP 上提供此服务,这可以解决它,但在您的环境中可能无法实现。您可以要求您的所有客户都使用除 Chrome 之外的其他东西,但这是不切实际的。或者你可以为 Flask 提供一个不同的会话接口,它对已经用于 localhost 的 IP 执行相同的解决方法,尽管这在某些方面可能是不安全的。

    Chrome 不允许使用域 IP 的 cookie,并且没有实际的解决方法。

    【讨论】:

      【解决方案2】:

      可以使用 IP 在 Chrome 浏览器中创建会话。

      我的配置文件有这些配置:

          SERVER_NAME = '192.168.0.6:5000'
          SESSION_COOKIE_DOMAIN = '192.168.0.6:5000'
      

      它允许我使用本地虚拟机,并且 cookie 在 Chrome 上完美运行,无需本地 FQDN。

      【讨论】:

        【解决方案3】:

        请注意,在 @davidism 发布的 localhost 解决方法中 -- https://github.com/mitsuhiko/flask/blob/master/flask/sessions.py#L211-L215 ,您可以修补 Flask 代码并将 if rv == '.localhost': rv = None 更改为简单的 rv = None ,然后不会设置 cookie 域并且您的 cookie 将工作。

        您不希望在真正的生产应用程序上执行此操作,但如果您的服务器只是某种没有敏感数据的测试/暂存服务器,那可能没问题。我这样做只是为了在192.168.x.x 地址上通过 LAN 测试一个应用程序,这很好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-20
          • 2015-07-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-05
          相关资源
          最近更新 更多