概要(Django セッション=「ブラウザごとの“一時的な記憶領域”」)
Django のセッションは、
「このブラウザは、前回どんな状態だったか」
をサーバー側に覚えておくための仕組みです。
ログイン状態
カートの中身
一時的な入力内容
こういったものを「ユーザーごと」「ブラウザごと」に保持したいとき、
セッションが活躍します。
ポイントは、
ブラウザには「セッション ID だけ」をクッキーで持たせて
実際の中身(データ)はサーバー側に保存する
という構造になっていることです。
ここから、
セッションのざっくりした仕組み
実際のコードでの使い方(読み書き・削除)
ログインとの関係
設計のときに意識しておきたい注意点
を、初心者向けにかみ砕いて説明していきます。
セッションの仕組みをイメージでつかむ
「クッキーには鍵だけ、中身はサーバー側」という構造
まず、セッションの基本的な考え方から。
ブラウザとサーバーは、
HTTP という「基本 stateless(状態を持たない)」プロトコルで会話しています。
つまり、本来は「前回のリクエストのことを覚えていない」のが普通です。
でも、Web アプリでは、
この人はログイン済みか
この人のカートには何が入っているか
この人は前の画面で何を入力していたか
などを覚えておきたい。
そこで Django は、
ブラウザには「セッション ID(ただの文字列)」だけをクッキーに保存し
その ID をキーにして、サーバー側に「セッションデータ」を保存する
という仕組みを使います。
流れをざっくり書くとこうです。
- 初回アクセス時、まだセッションがなければ新しいセッション ID を発行する
- その ID をクッキーに保存して、ブラウザに返す
- 次のリクエストでは、ブラウザがそのクッキー(セッション ID)を送ってくる
- サーバー側は「この ID に対応するセッションデータ」を取り出す
開発者としては、request.session という辞書っぽいオブジェクトを通して
セッションデータを読み書きするだけでよく、
クッキーや DB の細かいことは Django が面倒を見てくれます。
セッションは「ブラウザごとの一時的なストレージ」
セッションは、
ユーザーごと
ブラウザごと
に紐づく「一時的なストレージ」です。
同じユーザーでも、
PC の Chrome とスマホの Safari は別セッションになります。
また、セッションには有効期限があります。
一定時間アクセスがなかったり、
ブラウザを閉じたりすると、
セッションが切れることがあります。
「長期的に残したい情報」は DB に保存し、
「一時的に覚えておきたい情報」はセッションに入れる、
という役割分担を意識すると設計しやすくなります。
実際のコードで見る Django セッションの使い方
セッションに値を保存する(書き込み)
ビューの中では、request.session を辞書のように扱えます。
例えば、「カウンター」をセッションに保存してみます。
from django.http import HttpResponse
def counter_view(request):
count = request.session.get("count", 0)
count += 1
request.session["count"] = count
return HttpResponse(f"あなたはこのページに {count} 回アクセスしました。")
Pythonここでやっていることは、
request.session.get("count", 0) で、
セッションから “count” を取り出し、なければ 0 を使う
それに 1 を足して、request.session["count"] = count でセッションに保存する
という流れです。
同じブラウザでこのページをリロードすると、
カウントが 1, 2, 3… と増えていきます。
別のブラウザやシークレットウィンドウからアクセスすると、
別カウントになります。
これが「セッションごとの状態管理」です。
セッションから値を取り出す(読み込み)
読み込みは、先ほどのように get() を使うのが安全です。
user_name = request.session.get("user_name") # なければ None
Pythonキーが存在しない場合にエラーにしたくないときは、get("key", デフォルト値) を使います。
theme = request.session.get("theme", "light")
Pythonこのようにして、
「ユーザーが選んだテーマ」などをセッションに保存しておき、
次回アクセス時に反映する、という使い方もできます。
セッションから値を消す・全部消す
特定のキーだけ消したいときは del を使います。
if "count" in request.session:
del request.session["count"]
Pythonセッション全体をクリアしたいときは、flush() を使います。
request.session.flush()
Pythonこれは、
現在のセッションデータを全部削除し
新しいセッション ID を発行する
という動きをします。
ログアウト時などに使われることがあります
(ただし、通常は logout() が内部でよしなにやってくれます)。
セッションとログイン(認証)の関係
「ログイン状態」もセッションの上に乗っている
Django の認証(login/logout)は、
セッションの仕組みの上に乗っています。
login(request, user) を呼ぶと、
Django はセッションに「このセッションは user.id と紐づいている」という情報を書き込みます。
次のリクエストでは、
そのセッション ID をもとにユーザー情報が復元され、request.user にセットされます。
つまり、
セッションは「ログイン状態を覚えておくための土台」
認証は「誰なのかを判定して、その結果をセッションに載せる仕組み」
という関係です。
開発者としては、
ログイン機能は Django 認証に任せる
セッションは「ログイン以外の一時的な情報」にも使える
という整理をしておくと、頭がスッキリします。
「セッションを消す」と「ログアウト」の違い
logout(request) は、
「このユーザーのログイン情報をセッションから削除する」処理です。
一方、request.session.flush() は、
セッション全体を消して新しいセッションを作り直します。
ログアウトしたいだけなら、
基本的には logout() を使うのが正解です。
セッションにログイン以外の情報(カートなど)も入れている場合、flush() を使うとそれらも全部消えてしまうので、
用途に応じて使い分ける必要があります。
セッション設計で意識しておきたいこと
「何でもかんでもセッションに入れない」
セッションは便利なので、
つい何でもかんでも突っ込みたくなりますが、
いくつか注意点があります。
大きなデータ(巨大なリストや辞書)を入れすぎると、
セッションストア(デフォルトでは DB)が肥大化し、
パフォーマンスに影響します。
また、セッションは「一時的なもの」です。
有効期限が切れれば消えますし、
ユーザーがブラウザを変えれば別セッションになります。
なので、
長期的に保持したいデータ(ユーザー設定、履歴など)は DB に保存
一時的な状態(ウィザード形式の入力途中、カートの中身など)はセッション
という役割分担を意識するとよいです。
セキュリティ的な意識(セッション ID の扱い)
セッション ID は「そのユーザーになりすますための鍵」です。
Django は、
セッション ID を推測しにくいランダムな値にする
HTTPS を使っていれば暗号化された通信でクッキーを送るSESSION_COOKIE_SECURE や SESSION_COOKIE_HTTPONLY などの設定で
クッキーの安全性を高められる
といった対策を用意しています。
初心者のうちは、
細かい設定を全部覚える必要はありませんが、
セッション ID を URL に載せない
自分でセッション ID をいじらない
といった基本だけは意識しておくとよいです。
まとめ(Django セッションは「ユーザーごとの一時的な記憶装置」)
Django セッションを初心者目線で整理すると、こうなります。
セッションは「ブラウザごとの一時的な記憶領域」で、ブラウザにはセッション ID だけをクッキーで持たせ、中身はサーバー側に保存する仕組み。
ビューからは request.session を辞書のように扱うだけで、値の保存・取得・削除ができる。ログイン状態もこのセッションの上に乗っており、login() がセッションにユーザー情報を書き込む。
セッションには有効期限があり、長期的に残したい情報は DB に保存し、一時的な状態(カート、入力途中の情報など)をセッションに入れる、という役割分担を意識すると設計しやすい。
