I am attempting to track AnonymousUsers to figure out when they first come to the site, and when they then register to the website.
To do so, I created a middleware with the relevant functionality, but this initially assumed that each AnonymousUsers already had a session associated with it (i.e. sessionid cookie will be set in first response & associated session is already created in django_session). Note: session app & middleware are present
It seems that this is not the case, as looking at the session middleware, when an AnonymousUser first comes on the site, the session is never modified (Users do, since '_auth_user_id' and '_auth_user_backend' are set), and so is never created:
SessionMiddleware.process_response
def process_response(self, request, response):
"""
If request.session was modified, or if the configuration is to save the
session every time, save the changes and set a session cookie.
"""
try:
accessed = request.session.accessed
modified = request.session.modified
except AttributeError:
pass
else:
if accessed:
patch_vary_headers(response, ('Cookie',))
if modified or settings.SESSION_SAVE_EVERY_REQUEST:
if request.session.get_expire_at_browser_close():
max_age = None
expires = None
else:
max_age = request.session.get_expiry_age()
expires_time = time.time() + max_age
expires = cookie_date(expires_time)
# Save the session data and refresh the client cookie.
request.session.save()
response.set_cookie(settings.SESSION_COOKIE_NAME,
request.session.session_key, max_age=max_age,
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
path=settings.SESSION_COOKIE_PATH,
secure=settings.SESSION_COOKIE_SECURE or None,
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
return response
Attempt 1
To try and overcome this, in my Middleware, which is placed below the Session Middleware, I would force a save() on the session to create it:
if hasattr(request, 'session') and not request.session.session_key:
request.session.save()
This would provide the session_key, but unfortunately when SessionMiddleware.process_response is called, request.session.modified is still equal to False, and so the sessionid cookie is not set...
Attempt 2
One way to do this seems to modify the session, in an arbitrary way, to ensure that request.session.modified == True
, in the SessionMiddleware.process_response:
if hasattr(request, 'session') and not request.session.session_key:
request.session.save()
request.session['some_variable'] = True
This seems to fix my problem, without resorting to SESSION_SAVE_EVERY_REQUEST
, which would be an overkill, but yet it does not seem quite right....
Question
How to make sure the session is created for an AnonymousUser with no previous visit, without explicitly modifying the session, or having SESSION_SAVE_EVERY_REQUEST=True
?
Thanks for your help!
Even explicitly modifying the session can fail (eg assigning an attribute to a session attribute).
You need to explicitly set session.modified
to true
if hasattr(request, 'session') and not request.session.session_key:
request.session.save()
request.session.modified = True
Have a look at what the docs say on when sessions are saved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With