Python会话SAMESITE =未设置

时间:2020-07-20 09:50:56

标签: python flask samesite flask-session

我在chrome和SameSite方面遇到问题。我正在shopify iframe中提供网页,并且在使用flask-login设置会话时,chrome会告诉我这一点:

与位于以下位置的跨站点资源关联的cookie 网址未设置 SameSite属性。已被屏蔽,因为Chrome现在仅提供 跨站点请求的Cookie(如果已设置为SameSite=None) 和Secure

设置了安全性,但是我试图以所有可能的方式设置SameSite,但没有效果。

我尝试设置

app.config ['SESSION_COOKIE_SAMESITE'] =“无”

我尝试过,更改了库的行为,我很累在set_cookie()中设置属性,但似乎没有任何效果。我看到的响应没有SameSite属性。

(我有flask的最新版本,flask-login,flask-security和werkzeug)

你能帮我吗?

谢谢

3 个答案:

答案 0 :(得分:1)

只需对此进行扩展,就像您提到的那样,使用flask应用程序配置,就可以设置所有内容,除非设置SESSION_COOKIE_SAMESITE=None时Google Chrome似乎没有将该值设置为“ None”,然后默认进入“宽松”状态。

我如何解决此问题是将Cookie重新添加到响应标头中。首先,我必须获取cookie值,因为使用request.cookies.get("my_cookie")似乎没有从响应中提取cookie值,并且总是显示为None。

其次,使用response.set_cookie()仍未设置samesite=None的值。我不知道为什么,因为我使用的是最新版本的flaskWerkzeug,显然应该可以解决问题,但不能解决。经过大量测试,我发现使用response.headers.add()可以添加一个Set-Cookie:头,但是我需要一种提取cookie值的方法来确保可以得到相同的会话。在浏览Flask文档和其他在线论坛之后。我发现我实际上可以调用SecureCookieSessionInterface类并从那里进行签名的会话。

from flask import session
from flask.sessions import SecureCookieSessionInterface

# where `app` is your Flask Application name.
session_cookie = SecureCookieSessionInterface().get_signing_serializer(app)

最后,我必须确保在建立请求之后,将相同的会话添加到响应中,而不是在成熟的应用程序中似乎不可行的每条路由上都调用它。这是通过使用after_request装饰器完成的,该装饰器在请求后自动运行。

@app.after_request
def cookies(response):
    same_cookie = session_cookie.dumps(dict(session))
    response.headers.add("Set-Cookie", f"my_cookie={same_cookie}; Secure; HttpOnly; SameSite=None; Path=/;")
    return response

我在Chrome中注意到的是,它基本上会设置一个具有相同签名值的重复cookie。由于两者都与响应标头中带有samesite=None的一个相同,而另一个被Chrome阻止的元素似乎被忽略了。因此,可以使用flask应用程序验证会话并允许访问。

答案 1 :(得分:1)

一个容易犯的错误(就像我一样)是将 None"None" 混淆。确保使用字符串而不是 python 文字,如下所示:

response.set_cookie("key", value, ..., samesite="None")

samesite=None 确实会被忽略并默认为“Lax”。

答案 2 :(得分:0)

来自:https://github.com/GoogleChromeLabs/samesite-examples/blob/master/python-flask.md

假设您使用的是包含the fix to this issuewerkzeug的最新版本,则应该可以使用 set_cookie() 像这样:

from flask import Flask, make_response

app = Flask(__name__)

@app.route('/')
def hello_world():
    resp = make_response('Hello, World!');
    resp.set_cookie('same-site-cookie', 'foo', samesite='Lax');
    resp.set_cookie('cross-site-cookie', 'bar', samesite='None', secure=True);
    return resp

否则,您仍然可以 set the header 明确地:

from flask import Flask, make_response

app = Flask(__name__)

@app.route('/')
def hello_world():
    resp = make_response('Hello, World!');
    resp.set_cookie('same-site-cookie', 'foo', samesite='Lax');
    # Ensure you use "add" to not overwrite existing cookie headers
    resp.headers.add('Set-Cookie','cross-site-cookie=bar; SameSite=None; Secure')
    return resp