セッションを一言でいうと
セッションは
「同じユーザーからの一連のリクエストを“ひとまとまり”として扱うためのサーバー側の仕組み」
です。
HTTP は本来「1 回 1 回がバラバラで、前後のつながりを覚えない」プロトコルですが、
セッションを使うことで、
「このリクエストは、さっきログインしたあのユーザーからだ」と認識できるようになります。
ログイン状態の維持、カートの中身の保持、ウィザード形式の入力など、
“継続している状態”が必要な場面で必ず出てくる概念です。
HTTP が「覚えてくれない」からセッションが必要になる
ステートレスな HTTP の限界
HTTP はステートレス(無状態)です。
1 回目のリクエストと 2 回目のリクエストの間に、
「これは同じ人だよ」という情報は、プロトコル的には一切ありません。
だから、そのままだと
ログインしても、次のリクエストで誰だか分からない
カートに商品を入れても、次の画面で忘れられる
「前の画面で入力した内容」を引き継げない
という状態になります。
ここで登場するのが「セッション」です。
セッションの直感イメージ
セッションは、
「サーバー側に置いておく“ユーザーごとのメモ帳”
だと思ってください。
「このユーザーはログイン済み」
「このユーザーのカートには商品 A と B が入っている」
といった情報を、
サーバー側のメモ帳(セッションストア)に保存しておき、
次のリクエストでもそれを参照できるようにします。
セッションと Cookie の関係
セッション ID という“鍵”を Cookie に入れる
サーバー側に「ユーザーごとのメモ帳(セッション)」を作ったとして、
問題は「どのメモ帳がどのユーザーのものか」をどうやって見分けるか、です。
そこで使うのが「セッション ID」です。
流れはこうなります。
サーバーがランダムなセッション ID(例:abc123)を発行する
サーバー側に「abc123 → ユーザーID=1、ログイン済み」などの情報を保存する
レスポンスで Set-Cookie: JSESSIONID=abc123 を返す
ブラウザは JSESSIONID=abc123 を保存し、次回以降のリクエストで Cookie: JSESSIONID=abc123 を送る
サーバーは abc123 を見て、対応するセッション情報を取り出す
つまり、
セッションの中身(ログイン状態など)はサーバー側に置く
そのセッションを指す“鍵(ID)”だけを Cookie に入れてブラウザに持たせる
という分担になっています。
なぜ中身を Cookie に入れないのか
Cookie はクライアント側で見えるし、書き換えもできます。
もし「ユーザーID=1」などをそのまま Cookie に入れて信用してしまうと、
書き換えられて不正アクセスされる危険があります。
だから、
Cookie には「意味のないランダムな ID(セッション ID)」だけ
本当の情報(ユーザー ID、権限、カートの中身など)はサーバー側のセッションに保存
という設計が安全です。
Java(Spring)におけるセッションのイメージ
JSESSIONID と HttpSession
Java(サーブレット/Spring)では、
セッションは HttpSession というオブジェクトで扱います。
ブラウザからのリクエストに対して、
サーバーは自動的にセッションを作り、JSESSIONID という Cookie でセッション ID をやり取りします。
コードのイメージはこんな感じです。
@GetMapping("/login-success")
public String loginSuccess(HttpServletRequest request) {
HttpSession session = request.getSession(); // なければ新規作成
session.setAttribute("userId", 1L);
session.setAttribute("userName", "Alice");
return "redirect:/mypage";
}
Java次のリクエストでは、同じセッションを取り出せます。
@GetMapping("/mypage")
public String mypage(HttpServletRequest request, Model model) {
HttpSession session = request.getSession(false); // なければ null
if (session == null) {
return "redirect:/login";
}
Long userId = (Long) session.getAttribute("userId");
String userName = (String) session.getAttribute("userName");
if (userId == null) {
return "redirect:/login";
}
model.addAttribute("userName", userName);
return "mypage";
}
Javaここで重要なのは、
「セッションはサーバー側のメモ帳であり、Cookie はそのメモ帳の鍵を持っているだけ」
という構造です。
セッションがよく使われる場面
ログイン状態の維持
典型的な例はログインです。
ログイン成功時に
セッションに userId や roles(権限)を保存する
以降のリクエストでセッションを見て「この人は誰か」「何ができるか」を判断する
という流れになります。
Spring Security を使うと、
このあたりをフレームワークがかなり自動化してくれますが、
裏側では結局「セッション+Cookie」でユーザーを識別しています。
カートや一時的な入力内容の保持
EC サイトのカート
複数画面にまたがる入力フォーム(ステップ 1 → 2 → 3)
なども、セッションに一時的に保存しておくことが多いです。
ただし、
セッションに入れすぎるとメモリを圧迫するので、
「何でもかんでもセッションに突っ込む」のは NG です。
セッションで気をつけるべきポイント(重要)
1. セッションはサーバーのリソースを消費する
セッションはサーバー側のメモリやストレージを使います。
ユーザーが増えるほど、セッションも増えます。
だから、
不要になったセッションはタイムアウトで破棄する
巨大なデータをセッションに入れない
といった設計が必要です。
2. セッション固定攻撃などのセキュリティリスク
セッション ID が盗まれたり、
攻撃者に固定されたりすると、
「なりすまし」が起きます。
ログイン前後でセッション ID を再発行する
セッション ID を URL に埋め込まない(Cookie でやり取りする)Secure や HttpOnly を付ける
などの対策が重要です。
3. REST 的な世界では「できるだけステートレス」が好まれる
REST API の設計では、
「サーバー側にセッション状態を持たない(ステートレス)」
ことが理想とされます。
その代わりに、
各リクエストにトークン(JWT など)を付けて認証する、
というスタイルがよく使われます。
とはいえ、
ブラウザベースの Web アプリでは、
今でもセッション+Cookie は現役バリバリです。
初心者向けまとめ:セッションを自分の言葉で説明するなら
あなたの言葉で整理すると、こうなります。
セッションは、
「ステートレスな HTTP の上に、“同じユーザーからの一連のリクエスト”をひとまとまりとして扱うための、サーバー側のメモ帳」。
サーバーはランダムなセッション ID を発行し、
その ID とユーザー情報・ログイン状態などをサーバー側に保存する。
ブラウザには Cookie(JSESSIONID など)でその ID だけを渡し、
次回以降のリクエストでその ID を送り返してもらうことで、
「このリクエストは誰のものか」を認識できる。
もしよければ、
「ログイン成功 → マイページ表示」までの流れを、
セッションと Cookie の視点で自分の言葉で図解してみて。
それを説明できるようになったとき、セッションはもう“フレームワークの黒魔術”じゃなくて、あなたが理解してコントロールできる仕組みになっているはず。

