Hi,
-- So we are currently doing a project where the client wants the session to expire at browser close and also prevent multiple logins from the same account. Well there are some ways to implement the multiple login thing, consider this say user closes the browser, the session cookie expires. When a new request comes in we cannot validate this to see if this is a new login request because of expiry or if this a second login from the same account. So there's no good way to implement this(I think).
I suggested this, have a rigid session expiry that is it expires in 'N' hours/minutes/seconds, So when a new request comes in we can validate with the session expiry in the db. If the session has not expired we know that he's trying to login for a second time.
. I needed to change the session middleware to set the outgoing cookie only once. I only modified process_response, I pasted it below. I also added a new seessionstore class override two methods. The logic is simple, for the first time when a new request comes in, load is never invoked. So in create_db_instance we set an expiry date. When ever people try to modify the session, the load is invoked and we can get the expiry of the exisiting session from that.
It's works fine without any side affects. From what I understand after reading through session modules for a 3 straight days, I am just posting it here so that I know if I have not done some thing stupid, I want to have a second set of eyes to validate my approach.
class NewSessionStore(SessionStore):
actual_expiry=None
def _get_session_from_db(self):
try:
return self.model.objects.get(
session_key=self.session_key,
expire_date__gt=timezone.now()
)
except (self.model.DoesNotExist, SuspiciousOperation) as e:
if isinstance(e, SuspiciousOperation):
logger = logging.getLogger(
'django.security.%s' % e.__class__.__name__)
logger.warning(str(e))
self._session_key = None
def load(self):
#print("In load")
s = self._get_session_from_db()
if s:
self.actual_expiry=s.expire_date
return self.decode(s.session_data) if s else {}
def create_model_instance(self, data):
"""
Return a new instance of the session model object, which represents the
current session state. Intended to be used for saving the session data
to the database.
"""
#print("In create_model_instance")
if not self.actual_expiry:
from datetime import datetime
print("Expire Time thats being set",datetime.now())
self.actual_expiry=self.get_expiry_date()
return self.model(
session_key=self._get_or_create_session_key(),
session_data=self.encode(data),
expire_date=self.actual_expiry,
)
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 or delete
the session cookie if the session has been emptied.
"""
try:
accessed = request.session.accessed
modified = request.session.modified
empty = request.session.is_empty()
except AttributeError:
pass
else:
# First check if we need to delete this cookie.
# The session should be deleted only if the session is entirely empty
if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
response.delete_cookie(
settings.SESSION_COOKIE_NAME,
path=settings.SESSION_COOKIE_PATH,
domain=settings.SESSION_COOKIE_DOMAIN,
)
else:
if accessed:
patch_vary_headers(response, ('Cookie',))
if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
if request.session.get_expire_at_browser_close():
max_age = None
expires = None
else:
max_age = request.session.get_expiry_age()
if request.COOKIES.get(settings.SESSION_COOKIE_NAME):
pass
else:
expires_time = time.time()+max_age
expires = http_date(expires_time)
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,
)
# Save the session data and refresh the client cookie.
# Skip session save for 500 responses, refs #3881.
if response.status_code != 500:
try:
request.session.save()
except UpdateError:
raise SuspiciousOperation(
"The request's session was deleted before the "
"request completed. The user may have logged "
"out in a concurrent request, for example."
)
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/b754ba38-f4bf-4f5f-8db6-e5eb1b0759da%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment