diff --git a/gluon/globals.py b/gluon/globals.py index 26fba47c..d557294b 100644 --- a/gluon/globals.py +++ b/gluon/globals.py @@ -1075,6 +1075,8 @@ class Session(Storage): scookies['HttpOnly'] = True if self._secure: scookies['secure'] = True + if self._same_site: + scookies['samesite'] = self._same_site def clear_session_cookies(self): request = current.request @@ -1153,6 +1155,12 @@ class Session(Storage): def secure(self): self._secure = True + def samesite(self, mode='Lax'): + if 'samesite' not in Cookie.Morsel._reserved: + # Python version 3.7 and lower needs this + Cookie.Morsel._reserved['samesite'] = 'SameSite' + self._same_site = mode + def forget(self, response=None): self._close(response) self._forget = True @@ -1180,7 +1188,7 @@ class Session(Storage): def _unchanged(self, response): if response.session_new: - internal = ['_last_timestamp', '_secure', '_start_timestamp'] + internal = ['_last_timestamp', '_secure', '_start_timestamp', '_same_site'] for item in self.keys(): if item not in internal: return False diff --git a/gluon/tests/test_globals.py b/gluon/tests/test_globals.py index 666249fa..b8c66dd8 100644 --- a/gluon/tests/test_globals.py +++ b/gluon/tests/test_globals.py @@ -231,6 +231,24 @@ class testResponse(unittest.TestCase): cookie = str(current.response.cookies) self.assertTrue('httponly' not in cookie.lower()) + def test_cookies_samesite(self): + current = setup_clean_session() + current.session._fixup_before_save() + cookie = str(current.response.cookies) + self.assertTrue('samesite' not in cookie.lower()) + + current = setup_clean_session() + current.session.samesite() + current.session._fixup_before_save() + cookie = str(current.response.cookies) + self.assertTrue('samesite=lax' in cookie.lower()) + + current = setup_clean_session() + current.session.samesite('Strict') + current.session._fixup_before_save() + cookie = str(current.response.cookies) + self.assertTrue('samesite=strict' in cookie.lower()) + def test_include_meta(self): response = Response() response.meta[u'web2py'] = 'web2py'