🐙

セッションとクッキーの仕組みをしっかりと理解する【PHP】

に公開

はじめに

Webアプリケーション開発で必ず出てくる「セッション」と「クッキー」。
なんとなく使っているけど、実際どこに何が保存されているのか、ちゃんと理解できていますか?

この記事では、セッションとクッキーの違い、それぞれの保存場所、使い分けを分かりやすく解説します。

セッションとクッキーの違い

まず最初に押さえておくべき重要なポイントがあります。

セッションとクッキーは保存場所が違います。

  • セッション:実データはサーバー側に保存される
  • クッキー:データはブラウザ(クライアント側)に保存される

セッションの仕組み

セッションは2つの要素で成り立っている

セッションを使うとき、実は2箇所にデータが保存されています。

1. サーバー側:セッションファイル(実データ)

session_start();
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'taro';

このコードを実行すると、サーバーのどこかにこんなファイルが作られます。

/var/tmp/sess_abc123def456

ファイルの中身はこんな感じです。

user_id|i:123;username|s:4:"taro";

2. クライアント側:クッキー(セッションIDだけ)

ブラウザにはセッションIDだけがクッキーとして保存されます。

PHPSESSID=abc123def456

セッションが動く流れ

  1. ユーザーが初めてサイトにアクセス
  2. session_start() が実行される
  3. サーバーがセッションIDを生成して、空のセッションファイルを作る
  4. ブラウザに「このセッションIDを保存してね」と自動的にクッキーを送る
  5. 次回アクセス時、ブラウザがセッションIDを送ってくる
  6. サーバーがそのIDでファイルを特定して、$_SESSION を復元する

重要なポイント

session_start() を書くだけで、PHPが自動的に以下のことをやってくれます。

  • セッションIDの生成
  • サーバーへのセッションファイル作成
  • ブラウザへのクッキー保存

つまり、開発者は session_start() と書くだけでOKです。

セッション変数はどこに保存される?

$_SESSION['login_limit'] = 3600;
$_SESSION['user_id'] = 123;
$_SESSION['login_date'] = time();

これらはすべてサーバー側のセッションファイルに保存されます。

クッキーに保存されるのはセッションIDだけです。

なぜこの仕組みなのか?

セキュリティのためです。

もし $_SESSION['user_id'] などの重要な情報をクッキーに直接保存すると、ユーザーが改ざんできてしまいます。サーバー側に保存することで、ユーザーは自分のデータを勝手に変更できなくなります。

セッションファイルの保存場所

デフォルトの保存場所

PHPのデフォルト設定では、セッションファイルは以下の場所に保存されます。

Linux/Unix系サーバー

/tmp/

MAMP(Mac)

/Applications/MAMP/tmp/php/

MAMP(Windows)

C:\MAMP\tmp\php\

保存場所を変更する

session_save_path("/var/tmp/");
session_start();

session_save_path() で保存場所を変更できます。これは session_start() の前に書く必要があります。

確認方法

実際にどこに保存されているか確認するコードです。

session_start();
echo "セッション保存場所: " . session_save_path() . "<br>";
echo "セッションID: " . session_id();

ターミナルやエクスプローラーでそのディレクトリを見ると、sess_ で始まるファイルが見つかります。

セッションの有効期限設定

よくあるセッション設定コード

session_save_path("/var/tmp/");
ini_set('session.gc_maxlifetime', 60*60*24*30);
ini_set('session.cookie_lifetime', 60*60*24*30);
session_start();

このコードの意味を1つずつ見ていきましょう。

サーバー側のセッションファイルの有効期限

ini_set('session.gc_maxlifetime', 60*60*24*30);

サーバー側のセッションファイルの有効期限を30日に設定しています。

PHPのガーベージコレクション(古いセッションファイルを削除する仕組み)が、この期限を過ぎたファイルを削除対象にします。

ブラウザ側のクッキーの有効期限

ini_set('session.cookie_lifetime', 60*60*24*30);

ブラウザに保存されるセッションIDのクッキーの有効期限を30日に設定しています。

デフォルトは 0(ブラウザを閉じたら削除)なので、これを設定することでブラウザを閉じても30日間はセッションが維持されます。

両方設定する必要がある理由

セッションを長持ちさせるには、サーバー側とクライアント側の両方の設定が必要です。

  • サーバー側だけ設定:ブラウザを閉じるとクッキーが消えてセッションIDが分からなくなる
  • クライアント側だけ設定:サーバーのファイルが削除されてしまう

両方を同じ期限に設定することで、初めて長期間のセッション維持が実現できます。

セッションIDが変わるタイミング

セッションIDは通常のページ遷移では変わりません。以下のタイミングで新しいIDに切り替わります。

1. ログイン時(重要)

// Laravelなどのフレームワークでは自動
Auth::login($user);

// 素のPHPでは手動で再生成
session_regenerate_id(true);

ログイン成功時にセッションIDを再生成します。これは「セッション固定攻撃」を防ぐための重要なセキュリティ対策です。

2. 手動で再生成した時

session_regenerate_id();

3. セッションの有効期限切れ

設定された時間が経過すると、古いセッションは無効になり、次回アクセス時に新しいセッションIDが発行されます。

4. ブラウザを閉じた後(設定による)

クッキーの有効期限が 0 の場合、ブラウザを閉じるとクッキーが削除され、次回アクセス時に新しいセッションが始まります。

注意点

毎回 session_regenerate_id() を呼ぶのは問題があります。ページアクセスごとに毎回セッションIDが変わってしまうと、複数タブで開いている場合に古いタブのセッションが無効になってしまいます。

通常はログイン時や権限変更時など、重要なタイミングだけで再生成すべきです。

手動でクッキーを設定する方法

セッションとは別に、自分で好きなデータをクッキーとして直接ブラウザに保存したい場合があります。

setcookie() の使い方

setcookie('VISIT_COUNT', 1);

これは、自分で好きなキーと値をクッキーとしてブラウザに直接保存するコードです。

セッションとの違い

セッション($_SESSION)

session_start();
$_SESSION['user_id'] = 123; // サーバー側に保存
  • 実データはサーバー側のファイルに保存される
  • クッキーにはセッションIDだけ
  • 自動的に管理される

手動のクッキー(setcookie())

setcookie('VISIT_COUNT', 1); // ブラウザに直接保存
  • データがブラウザに直接保存される
  • 自分で明示的に設定・管理する必要がある

よくある使用例

// 訪問回数をカウント
setcookie('VISIT_COUNT', 1, time() + 60*60*24*30);

// ダークモード設定を保存
setcookie('theme', 'dark', time() + 60*60*24*365);

// 言語設定を保存
setcookie('lang', 'ja', time() + 60*60*24*365);

setcookie() の引数

setcookie(
  'VISIT_COUNT',           // 名前(キー)
  1,                       // 値(バリュー)
  time() + 60*60*24*30,    // 有効期限(30日後)
  '/',                     // パス
  '',                      // ドメイン
  false,                   // HTTPSのみか
  true                     // JavaScriptからアクセス不可にするか
);

クッキーの読み取り

// 次回アクセス時
if(isset($_COOKIE['VISIT_COUNT'])) {
  echo $_COOKIE['VISIT_COUNT'];
}

$_COOKIE['VISIT_COUNT'] で、ブラウザから送られてきたクッキーの中に VISIT_COUNT というキーがあるかを確認できます。

クッキーが届く流れ

  1. 前回のアクセス時に setcookie() でブラウザに保存
  2. 次回アクセス時、ブラウザが自動的にクッキーをHTTPリクエストヘッダーに含めて送信
   Cookie: VISIT_COUNT=1; PHPSESSID=abc123; theme=dark
  1. PHPが自動的に $_COOKIE に展開
   $_COOKIE = [
     'VISIT_COUNT' => '1',
     'PHPSESSID' => 'abc123',
     'theme' => 'dark'
   ];
  1. $_COOKIE['VISIT_COUNT'] で値を取得できる

まとめ

セッションとクッキーの違いを表にまとめます。

項目 セッション クッキー(手動)
保存場所 サーバー側 ブラウザ側
保存されるもの 実データ 実データ
クッキーに保存 セッションIDだけ すべてのデータ
使い方 $_SESSION['key'] = 'value' setcookie('key', 'value')
読み取り $_SESSION['key'] $_COOKIE['key']
セキュリティ 高い(ユーザーが改ざん不可) 低い(ユーザーが改ざん可能)
用途 ログイン状態、重要な情報 テーマ設定、言語設定など

使い分けの基本

  • セッション:ユーザーIDやログイン情報など、改ざんされたくない重要なデータ
  • クッキー(手動):テーマ設定や言語設定など、改ざんされても問題ない設定情報

セッションとクッキーの仕組みを理解すると、Webアプリケーションがどうやってログイン状態を維持しているのか、なぜセキュリティ対策が必要なのかが見えてきますね。最近、いろんな学習したことがどんどんつながってきていて楽しいです(^^)引き続き、頑張ります🔥

Discussion