Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
899 views
in Technique[技术] by (71.8m points)

flask - Python session SAMESITE=None not being set

I am having issues with chrome and SameSite. I am serving a webpage in a shopify iframe and when setting the session using flask-login, chrome tells me this:

A cookie associated with a cross-site resource at URL was set without the SameSite attribute. It been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with SameSite=None and Secure.

Secure is set, but I tried to set SameSite in all the possible way, but without effect.

I tried setting

app.config['SESSION_COOKIE_SAMESITE'] = "None"

I tried, changing the behavior of the library, I tired setting the attribute in set_cookie() but nothing seemed to work. The response I see doesn't have the SameSite attribute.

(I have the last versions of flask, flask-login, flask-security and werkzeug)

Can you help me?

Thank you

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Just to expand on this, using flask application config just as you've mentioned, you can set everything except when setting SESSION_COOKIE_SAMESITE=None Google Chrome doesn't seem to place the value as "None", which then defaults to "Lax".

How i worked around this problem was to add the cookie back into the response header. First I had to get the cookie value because using request.cookies.get("my_cookie") doesn't seem to extract the cookie value from the response and always appears as None.

secondly, using the response.set_cookie() still doesn't set the samesite=None value. I have no idea why because i'm using the latest version of flask and Werkzeug which apparently should fix the problem but it doesn't. After lots of testing, I found out using the response.headers.add() works to add a Set-Cookie: header but I needed a way to extract the cookie value to ensure I can get the same session. After looking through flask docs and other online forums. I found out that I can actually call SecureCookieSessionInterface class and get the signed session from there.

from flask import session
from flask.sessions import SecureCookieSessionInterface

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

Lastly, i had to ensure that the same session is added to the response after the request has been established rather than calling it on every route which doesn't seem feasible within a full fledged application. This is done by using the after_request decorator which runs automatically after a 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

What I noticed in Chrome is that, it basically sets a duplicate cookie with the same signed value. Since both are identical with one having samesite=None in the response header and the other blocked by Chrome seems to be ignored. Thus, the session is validated with the flask app and access is allowed.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...