Opened 3 years ago

Last modified 3 years ago

#21514 new Bug

Session expiry dates should be in an ISO string instead of datetime

Reported by: n142857@… Owned by: nobody
Component: contrib.sessions Version: 1.6
Severity: Normal Keywords:
Cc: prasoon2211 Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


The documentation for Django 1.6 says (

Note that datetime and timedelta values are only serializable if you are using the PickleSerializer.

And that's true. For instance, using django-social-auth I got this session data:

{'facebook_state': 'zyuqNJsGiXBPubpnwV7Lgh5pqbkKiqk5', 'social_auth_last_login_backend': u'facebook', '_auth_user_id': 4, '_auth_user_backend': 'social_auth.backends.facebook.FacebookBackend', '_session_expiry': datetime.datetime(2013, 11, 18, 9, 21, 20, 75255, tzinfo=<UTC>)}.

Which will give this error on login when using JSONSerializer:

datetime.datetime(2013, 11, 18, 9, 21, 20, 75255, tzinfo=<UTC>) is not JSON serializable

Django ships now with JSONSerializer enabled, but Django is still actively putting datetimes in sessions, concretely in django/contrib/sessions/backends/ Since it's not a Django extension which is incompatible with the default behaviour, but Django itself, I think it's Django which must be fixed.

A solution is to serialize the datetime to ISO 8601 before storing it in the session.

Change History (5)

comment:1 Changed 3 years ago by Tim Graham

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

Where is the code that calls set_expiry() with a datetime? My guess is that it's somewhere in your own project or a third party module, not in Django itself. See also the documentation for set_expiry().

comment:2 Changed 3 years ago by anonymous

You're right. it's django-social-auth (, function complete_process) who sets an expiry date. (For future readers who use Django 1.6 and cannot log in through Facebook: use SOCIAL_AUTH_SESSION_EXPIRATION=False).

But django-social-auth does the right thing in passing a datetime, because it cannot do otherwise: passing a string to set_expiry is not documented (it's also not as easy as passing a date). So I think set_expiry should accept datetime (as it does now) and convert to string when storing.
At least, issue a warning/error in set_expiry if SESSION_SERIALIZER=JsonSerializer.

comment:3 Changed 3 years ago by Aymeric Augustin

Triage Stage: UnreviewedAccepted

I don't think the current behavior is the best we can do :)

comment:4 Changed 3 years ago by prasoon2211

Okay, the dates can of course be stored in the ISO format. But, there's a problem.

s = Session.objects.get(

There are code segments like this in other files under contrib/sessions/backends directory. Here, we are comparing between two datetime objects. If we store expiry date as a string, I don't see how will we be able to make such queries, at least now without using raw sql. If there's a solution to this, then we can fix this issue.

comment:5 Changed 3 years ago by prasoon2211

Cc: prasoon2211 added
Note: See TracTickets for help on using tickets.
Back to Top