Django sessionid disappears from cookies, user becomes anonymous

Viewed 225

I have developed a web application with Django, using Firebase (accessed through the Pyrebase python wrapper) as the database, and have just deployed it using Google App Engine.

I am having issues with the sessionid, but only on the web server - not when I run the app locally.

What happens on the web server is once the user is authenticated, the user's ID token is stored in the session dictionary via request.session['uid'] = idToken. When the user is directed to the home page, the app tries to retrieve idToken from the sessions dictionary, which sometimes works and sometimes doesn't. When it does work, it loads some user data on the home page, but when the user clicks on another page, it continues to randomly work or not.

A couple things I noticed are:

When I watch the storage section of the developer console, I see that the session storage and local storage remain empty, while Cookies carries the sessionid and csrftoken variables. Every time a new page is loaded, the sessionid is set to a new value - this doesn't happen when I run it locally.

Eventually, the sessionid disappears from Cookies, and the error in the console reports that the user is actually anonymous. So either the user logins in and automatically is set to an anonymous user, or logs in and within a few clicks is set to an anonymous user.

I've tried changing the session engine/storage settings, but nothing seems to work..

The relevant parts of the error message are listed below, which is caused when the user logins in and tries to retrieve the 'uid' variable from sessions:

KeyError at /dashboard/loaduserdata
'uid'

Traceback:

File "/env/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  35.             response = get_response(request)

File "/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/vmagent/app/dashboard/views.py" in loaduserdata
  64.       idtoken = request.session['uid']

File "/env/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py" in __getitem__
  55.         return self._session[key]

Exception Type: KeyError at /dashboard/loaduserdata
Exception Value: 'uid'
Request information:
USER: AnonymousUser

GET: No GET data

POST: No POST data

FILES: No FILES data

INSTALLED_APPS = ['dashboard', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles']

SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 1209600
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_NAME = 'sessionid'
SESSION_COOKIE_PATH = '/'
SESSION_COOKIE_SECURE = True
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_EXPIRE_SECONDS = 3600
SESSION_FILE_PATH = None
SESSION_SAVE_EVERY_REQUEST = True
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'

Any help is greatly appreciated, thanks!

1 Answers

Run locally app, always send requests to that same server. For horizontally scaled systems like App Engine, when you send request, it can be rerouted to different instance by load balancer. In this scenario the use of an independent cache like memcache is required.

Alternatively, by supporting session affinity, we can allow users to use the in-memory session state instead of opting for memcache.

By default, App Engine will not use session affinity. It can be enabled per version via a generated cookie, with no expiration. An app may contain a set of versions, with one, all, or none having session affinity enabled:

app.yaml
network:
  session_affinity: true | false
Related