You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

middleware.py 3.4KB

5 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import time
  2. from importlib import import_module
  3. from django.conf import settings
  4. from django.contrib.sessions.backends.base import UpdateError
  5. from django.core.exceptions import SuspiciousOperation
  6. from django.utils.cache import patch_vary_headers
  7. from django.utils.deprecation import MiddlewareMixin
  8. from django.utils.http import http_date
  9. class SessionMiddleware(MiddlewareMixin):
  10. def __init__(self, get_response=None):
  11. self.get_response = get_response
  12. engine = import_module(settings.SESSION_ENGINE)
  13. self.SessionStore = engine.SessionStore
  14. def process_request(self, request):
  15. session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
  16. request.session = self.SessionStore(session_key)
  17. def process_response(self, request, response):
  18. """
  19. If request.session was modified, or if the configuration is to save the
  20. session every time, save the changes and set a session cookie or delete
  21. the session cookie if the session has been emptied.
  22. """
  23. try:
  24. accessed = request.session.accessed
  25. modified = request.session.modified
  26. empty = request.session.is_empty()
  27. except AttributeError:
  28. pass
  29. else:
  30. # First check if we need to delete this cookie.
  31. # The session should be deleted only if the session is entirely empty
  32. if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
  33. response.delete_cookie(
  34. settings.SESSION_COOKIE_NAME,
  35. path=settings.SESSION_COOKIE_PATH,
  36. domain=settings.SESSION_COOKIE_DOMAIN,
  37. )
  38. else:
  39. if accessed:
  40. patch_vary_headers(response, ('Cookie',))
  41. if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
  42. if request.session.get_expire_at_browser_close():
  43. max_age = None
  44. expires = None
  45. else:
  46. max_age = request.session.get_expiry_age()
  47. expires_time = time.time() + max_age
  48. expires = http_date(expires_time)
  49. # Save the session data and refresh the client cookie.
  50. # Skip session save for 500 responses, refs #3881.
  51. if response.status_code != 500:
  52. try:
  53. request.session.save()
  54. except UpdateError:
  55. raise SuspiciousOperation(
  56. "The request's session was deleted before the "
  57. "request completed. The user may have logged "
  58. "out in a concurrent request, for example."
  59. )
  60. response.set_cookie(
  61. settings.SESSION_COOKIE_NAME,
  62. request.session.session_key, max_age=max_age,
  63. expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
  64. path=settings.SESSION_COOKIE_PATH,
  65. secure=settings.SESSION_COOKIE_SECURE or None,
  66. httponly=settings.SESSION_COOKIE_HTTPONLY or None,
  67. samesite=settings.SESSION_COOKIE_SAMESITE,
  68. )
  69. return response