概要
- Django 3.0 には最初からユーザーのログイン認証とセッション管理の機能があります
- しかしデフォルト設定のままでは今回のセキュリティ要件を満たせなかったので、設定を変更する必要がありました
- ブラウザを閉じたらセッションを終了する要件については、条件付きでの実現となりました
それぞれの要件と対応
1. 任意の有効期間を設定したい
- デフォルト: 2 週間
- 希望要件: 15分間 〜 2時間の任意の期間に設定したい
設定方法
settings.py で定義します。
初期状態の settings.py では定義が省略されているので、例えば 1 時間に設定したい場合は以下の行を追記します。
SESSION_COOKIE_AGE = 3600
確認方法
データベースに接続して、新しいログインによって django_session
テーブルに挿入された行の expire_date
列の値が、ログイン時の UTC 時刻 + 設定した秒数になっていることで確認できます。
2. スマホのスリープのように、最後に操作してから放置した時間で期限切れにしたい
- デフォルト: ユーザーの操作に関係なく、ログイン時から
SESSION_COOKIE_AGE
秒後に期限が切れる - 希望要件: 最後にいずれかのページをロードしてから
SESSION_COOKIE_AGE
秒後に期限切れとしたい
設定方法
これも初期状態の settings.py では定義が省略されているので、以下の行を追記します。
SESSION_SAVE_EVERY_REQUEST = True
参考:
セッションが保存されるタイミング
SESSION_SAVE_EVERY_REQUEST
確認方法
データベースに接続して、画面をリロードするたびに django_session
テーブルの expire_date
列の値が更新されることで確認できます。
デフォルトではログイン認証時に expire_date
列の値が決まり、その後の操作で expire_date
列の値は更新されません。
3. セッションをデータベースで管理したい
- デフォルト: セッションをデータベースで管理する
これはデフォルトのままで希望どおりです。
サーバーのローカルメモリで管理する場合に比べてパフォーマンス面では不利ですが、ロードバランサーなどで前回と違うサーバーにリクエストが届いた場合でも正しく処理されます。
設定方法
初期状態の settings.py から変更する必要はありません。以下のとおりになっていればデータベースでセッションが管理されます。
-
INSTALLED_APPS
に"django.contrib.sessions"
が含まれていること -
MIDDLEWARE
に"django.contrib.sessions.middleware.SessionMiddleware"
が含まれていること -
SESSION_ENGINE
が定義されていないか、または設定値がdjango.contrib.sessions.backends.db
であること
参考: セッションエンジンを設定する
確認方法
データベースに接続して、ログインのたびに django_session
テーブルに新しい行が挿入されることで確認できます。
課題
django_session
テーブルに保存されたセッションの行は、明示的なログアウト処理(内部で django.contrib.auth.logout() の呼び出し)では削除されるのですが、有効期限が切れただけでは自動的に削除されません。
このため行が増え続けることを防ぐためには、以下のコマンドを時々実行して期限切れのセッションを削除する必要があります。
python manage.py clearsessions
4. Web ブラウザを閉じたらセッションを終了したい
- デフォルト: ブラウザを閉じても
SESSION_COOKIE_AGE
で設定された期限までセッションが維持される - 希望要件: 設定された期限に関係なく、ブラウザを閉じたらセッションを終了したい
設定方法
これも初期状態の settings.py では省略されているので、以下の行を追記します。
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
参考:
ブラウザ起動中のみ有効なセッション vs. 永続的なセッション
SESSION_EXPIRE_AT_BROWSER_CLOSE
確認方法
ブラウザを閉じてから起動して、同じページを開こうとするとログインを求められます。
デフォルトでは再ログインすることなく同じページが開きます。
課題
この動作はブラウザ自身が終了時に cookie を破棄するかどうかに依存しているため、以下のブラウザと設定では、ブラウザを閉じてもセッションが終了しませんでした。
- Google Chrome 85: 「設定」>「起動時」>「前回開いていたページを開く」が選択されている場合
- Firefox 80: 「設定」>「一般」>「起動」>「前回のセッションを復元する」が有効な場合