Two Django applications(DRF) are running on two separate ports 8001 and 8000 with same host localhost. I am using memcached to store the sessions. Both the application share the sessions from the memcache. when i try to access pages using second application after logining in using first I am getting error :
“The request’s session was deleted before the request completed. The user may have logged out in a concurrent request, for example.”
I want to build a distributed apps where one app can be used for auth running on a separate docker, so other apps can share the session using memcached
Sessionmiddleware is able to populate the session object in the Request object, but after execution of below line of code in AuthenticationMiddleware
request.user = SimpleLazyObject(lambda: get_user(request))
The session._session dictionary elements got deleted.
2
Answers
To solve this issue we need to add the same secret key in the settings in both Django applications. Django adds the user in the request body in authmiddleware. The user can be anonymous(unauthenticated) or authenticated user. The session is verified before adding the user in the request. This verification is done as follows.
session_hash_verified = session_hash and constant_time_compare( session_hash, user.get_session_auth_hash() )
This user.get_session_auth_hash() function uses salted_hmac(key_salt, self.password).hexdigest() function for verification. salted_hmac function uses settings.SECRET_KEY for calculating the hash. If both applications secret keys are different then session hasj will not be varified.
In the above case you are running application on two different ports with the same database. If
user1
logged in with port8000
then a session will be created for him. And againuser1
logged in with port8001
then the existing session will be replaced/destroyed by the new session. Because browser treatslocalhost:8000
andlocalhost:8001
as two different domains.To avoid it you can use
nginx
as areverse proxy
server with same ip127.0.0.1
or domainlocalhost
. Now, route the api requests to port8001
and web requests to port8000
.In above case the domain
localhost
remains same sodjango
will not replace existing session. So, It will work.Reference: https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/