为什么会话 cookie 在从域提供服务时有效,但在使用 IP 时却无效?

2024-04-21

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

更具体地说,未设置会话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)

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

会议does似乎可以在 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)

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

RFC 2109 https://www.rfc-editor.org/rfc/rfc2109#section-4.3.2描述了 cookie 的处理方式,似乎表明 cookie 域必须是带有 TLD(.com、.net 等)的 FQDN,或者是完全匹配的 IP 地址。这原始 Netscape cookie 规范 https://web.archive.org/web/20010322201006/http://www.netscape.com/newsref/std/cookie_spec.html根本没有提到IP地址。

Chrome 开发人员决定比其他浏览器更加严格地规定他们接受的 cookie 域值。虽然在某一时刻他们纠正了一个错误 https://code.google.com/p/chromium/issues/detail?id=3699阻止 IP 地址上的 cookie,他们显然已经倒退了 https://code.google.com/p/chromium/issues/detail?id=56211从那时起,不允许在非 FQDN 域(包括本地主机)上使用 cookieorIP 地址。他们已经表示他们will not解决这个问题,因为他们不认为这是一个错误。

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

在开发过程中,您可以通过在本地主机上运行应用程序来解决此问题,而不是让它默认为 127.0.0.1。Flask 有一个解决方法 https://github.com/mitsuhiko/flask/blob/master/flask/sessions.py#L211-L215如果服务器名称是 localhost,则不会发送会话 cookie 的域。app.run('localhost')

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么会话 cookie 在从域提供服务时有效,但在使用 IP 时却无效? 的相关文章

随机推荐