I am having trouble persisting my session variables in a webapp2 session store, while running on GAE. I have created a super simple app to reproduce the issue:
class MainHandler(webapp2.RequestHandler):
def post(self):
session = self.session_store.get_session()
previous_value = session.get("myvalue")
self.response.write(previous_value)
def get(self):
session = self.session_store.get_session()
previous_value = session.get("myvalue")
self.response.write(previous_value)
session["myvalue"] = "Hi! " + (previous_value if previous_value else "")
# this is needed for webapp2 sessions to work
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
super(MainHandler, self).dispatch()
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
The premise here is that the get
request sets a session variable while the post
simply writes to the response object.
My understanding is that after performing the get
request, the session persists myvalue
. After that, if I perform a post
request, then a get
request again, myvalue
should still be there, even though I didn't set it again in the post
handler. Alas, that is not the case:
>>> cookies = None
>>> for i in range(10):
... r = requests.get("http://localhost:11282/", cookies=cookies)
... cookies = r.cookies
... print r.text
...
None
Hi!
Hi! Hi!
Hi! Hi! Hi!
Hi! Hi! Hi! Hi!
Hi! Hi! Hi! Hi! Hi!
Hi! Hi! Hi! Hi! Hi! Hi!
Hi! Hi! Hi! Hi! Hi! Hi! Hi!
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi!
Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi! Hi!
>>>
>>> cookies = None
>>> for i in range(10):
... r = requests.get("http://localhost:11282/", cookies=cookies)
... cookies = r.cookies
... print r.text
... r = requests.post("http://localhost:11282/", cookies=cookies)
... cookies = r.cookies
... print r.text
...
None
Hi!
None
Hi!
None
Hi!
None
Hi!
None
Hi!
None
Hi!
None
Hi!
None
Hi!
None
Hi!
None
Hi!
Since I am fairly new to web technologies and standards, I seem to have missed something:
def save_session(self, response):
if self.session is None or not self.session.modified:
return
This is the implementation of SecureCookie
. Since the cookie is not saved to the response if it is not modified, I am guessing that per standard/protocol, the backend is not responsible for sending the cookie again, as it should already be on the client. It would be great to find a reference to this.
This proves it (switching to requests.Session()
):
>>> s = requests.Session()
>>> for i in range(5):
... r = s.get("http://localhost:11282/")
... print r.text
... r = s.post("http://localhost:11282/")
... print r.text
...
None
POST
Hi!
POST
Hi! Hi!
POST
Hi! Hi! Hi!
POST
Hi! Hi! Hi! Hi!
POST
>>>