Djangoフレームワークのセッションの有効期限

Djangoフレームワークのセッションの有効期限について調べる必要があったのでまとめておく。

試したバージョンは、Python 3.9、Django 3.2.4。

ドキュメント

セッションのデフォルト設定

Djangoでプロジェクト生成した際のデフォルトの settings.py では、セッションのアプリケーションは有効になっている。

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',  # セッションアプリケーション
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',  # セッションミドルウェア
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

その他にセッションの設定は記載されていないので、デフォルトの設定が使われる。

デフォルトの設定値は、ドキュメントに記載がある。

https://docs.djangoproject.com/ja/3.2/ref/settings/#sessions

設定値の実装を確認したい場合は django.conf.global_settings のコードを読む。

https://github.com/django/django/blob/main/django/conf/global_settings.py

有効期限の扱い

Djangoのセッションは 「最後に更新されたときから有効期限の設定の期間」 が有効期限となる。

既存のセッションのデータがViewなどでの処理で更新された場合、 「有効期限が自動的に延長されていく」 といった仕様になる。

デフォルトの設定では、セッションのデータを参照するだけではセッションは更新されないので、 「最後にアクセスがあったときから~」ではない ことに注意する。

セッションの有効期限を延長する

Djangoのセッションの有効期限を延長したい場合は、セッションの更新を行う。

方法はいくつかある。

  • セッションの値を変更する
    • セッションの値を変更すると、バックエンドでデータが保存、更新されるため、有効期限が延長される
  • セッションの値は変更しないが明示的に更新する
    • request.session.modified = True のようにViewの中で記述しておくと、セッションミドルウェアで変更扱いとして保存、更新される
  • すべてのリクエストでセッションを保存する
    • settings.pyの SESSION_SAVE_EVERY_REQUESTTrue を指定すると、セッションが発行されている場合には、ミドルウェアによりすべてのリクエストでセッションが保存、更新される
    • この方法だと、 「リクエスト毎にセッションの有効期限が延長される」 というのを実現可能
    • SESSION_SAVE_EVERY_REQUEST = True の場合、セッションの保存先のストレージに書き込み処理が多数発生するので、負荷が問題にならないか気をつける必要がある。
class MyView(View):
    def get(self, request):
        ...
        # Viewでセッションの保存を行う場合はどちらかの方法でよい
        request.session["foo"] = "bar"  # セッションの値を更新する例

        request.session.modified = True   # 明示的にセッション保存を指定する例, セッションの値を更新した場合は不要
        ...

セッションが保存されるタイミングはドキュメントにも記載があるので、参考に。

https://docs.djangoproject.com/ja/3.2/topics/http/sessions/#when-sessions-are-saved