Reputation: 395
Due to changes arriving in Chrome during July, I need to modify my app to explicitly provide the SameSite=None key value. This is due to the RFC treating the absence of this setting in a more impacting way than if it is present but set to None.
However on the set_cookie method, the samesite parameter is defaulted to None which results in it not being written into the set-cookie. How can I force this into the set-cookie part of the response?
When I try to set the samesite=None with the following code
resp.set_cookie('abcid', 'Hello', domain=request_data.domain, path='/', samesite=None, max_age=63072000)
This does not show any SameSite detail in the returned set-cookie
abcid=Hello; Domain=.localhost; Expires=Tue, 29-Jun-2021 22:34:02 GMT; Max-Age=63072000; Path=/
And if I try and explicitly set the value of Lax (which is one of the accepted values per rfc) as so
resp.set_cookie('abcid', "Hello", domain=request_data.domain, path='/', samesite="Lax", max_age=63072000)
I get back the set-cookie which explicitly has the SameSite=Lax setting
abcid=Hello; Domain=.localhost; Expires=Tue, 29-Jun-2021 23:03:10 GMT; Max-Age=63072000; Path=/; SameSite=Lax
I have tried None, "None", and "" but these either crash the application or omit the SameSite in the resultant response.
Any help would be gratefully received
Upvotes: 20
Views: 22407
Reputation: 11
Answering for the next time it comes up in a web search.
Just do this:
resp.set_cookie('abcid', 'Hello', domain=request_data.domain, path='/', samesite='None', secure=True, max_age=63072000)
Need to provide a string, and set the string to literal 'None'.
Also need to set secure=True
, as samesite='None'
must be combined with secure=True
(Per old posts, there was a bug in Flask/ Werkzeug which didn't permit 'None'
, but as of December 2024, this is working fine!)
Upvotes: 0
Reputation: 21
You can also use the following code to set cookies with SameSite=None
until fix is released
from werkzeug.http import dump_cookie
# That's a workaround for explicitly setting SameSite to None
# Until the following fix is released:
# https://github.com/pallets/werkzeug/issues/1549
def set_cookie(response, *args, **kwargs):
cookie = dump_cookie(*args, **kwargs)
if 'samesite' in kwargs and kwargs['samesite'] is None:
cookie = "{}; {}".format(cookie, b'SameSite=None'.decode('latin1'))
response.headers.add(
'Set-Cookie',
cookie
)
Upvotes: 2
Reputation: 3050
Once the fix to this issue is
released, you will be able to use
set_cookie()
like this:
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='Lax', secure=True);
return resp
While you're waiting for the release, you can still set the header explicitly:
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
Upvotes: 13