signed_cookies.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. from django.conf import settings
  2. from django.contrib.sessions.backends.base import SessionBase
  3. from django.core import signing
  4. class SessionStore(SessionBase):
  5. def load(self):
  6. """
  7. We load the data from the key itself instead of fetching from
  8. some external data store. Opposite of _get_session_key(),
  9. raises BadSignature if signature fails.
  10. """
  11. try:
  12. return signing.loads(self.session_key,
  13. serializer=self.serializer,
  14. # This doesn't handle non-default expiry dates, see #19201
  15. max_age=settings.SESSION_COOKIE_AGE,
  16. salt='django.contrib.sessions.backends.signed_cookies')
  17. except Exception:
  18. # BadSignature, ValueError, or unpickling exceptions. If any of
  19. # these happen, reset the session.
  20. self.create()
  21. return {}
  22. def create(self):
  23. """
  24. To create a new key, we simply make sure that the modified flag is set
  25. so that the cookie is set on the client for the current request.
  26. """
  27. self.modified = True
  28. def save(self, must_create=False):
  29. """
  30. To save, we get the session key as a securely signed string and then
  31. set the modified flag so that the cookie is set on the client for the
  32. current request.
  33. """
  34. self._session_key = self._get_session_key()
  35. self.modified = True
  36. def exists(self, session_key=None):
  37. """
  38. This method makes sense when you're talking to a shared resource, but
  39. it doesn't matter when you're storing the information in the client's
  40. cookie.
  41. """
  42. return False
  43. def delete(self, session_key=None):
  44. """
  45. To delete, we clear the session key and the underlying data structure
  46. and set the modified flag so that the cookie is set on the client for
  47. the current request.
  48. """
  49. self._session_key = ''
  50. self._session_cache = {}
  51. self.modified = True
  52. def cycle_key(self):
  53. """
  54. Keeps the same data but with a new key. To do this, we just have to
  55. call ``save()`` and it will automatically save a cookie with a new key
  56. at the end of the request.
  57. """
  58. self.save()
  59. def _get_session_key(self):
  60. """
  61. Most session backends don't need to override this method, but we do,
  62. because instead of generating a random string, we want to actually
  63. generate a secure url-safe Base64-encoded string of data as our
  64. session key.
  65. """
  66. session_cache = getattr(self, '_session_cache', {})
  67. return signing.dumps(session_cache, compress=True,
  68. salt='django.contrib.sessions.backends.signed_cookies',
  69. serializer=self.serializer)
  70. @classmethod
  71. def clear_expired(cls):
  72. pass