本文へスキップ
BecomeCoder

PHPコース · 第7章 Webアプリの実務 · レッスン25

セッションとクッキー ― ログイン状態を覚えておく

ローカル実施

導入

Webの通信(HTTP)は基本的に「1回のリクエストごとに独立」していて、前回のアクセスを覚えていません。それなのに、ログインしたサイトでは次のページに移動しても「ログイン済み」のままです。これを実現しているのがセッションクッキーです(ブラウザの中では実際のHTTPリクエストが発生しないため、この章も読み物として進みます)。

説明

クッキー(Cookie は、サーバーがブラウザに「これを覚えておいて、次からのリクエストのたびに一緒に送り返して」と頼む小さなデータです。setcookie() で送り、$_COOKIE で読み取ります。

<?php
setcookie("username", "tanaka", time() + 3600);   // 1時間だけ有効なクッキーを送る
echo $_COOKIE["username"] ?? "未設定";

クッキーはブラウザ側(クライアント側)に保存されるため、ユーザーが中身を見たり書き換えたりできてしまいます。パスワードなどの重要な情報をクッキーに直接入れてはいけません。

セッション(Session) は、実際のデータはサーバー側に保存し、ブラウザには「どのセッションか」を示す小さなID(セッションID)だけをクッキーとして渡す仕組みです。session_start() を呼ぶと、そのIDを使ってサーバー側のデータ置き場($_SESSION)にアクセスできます。

<?php
session_start();   // ページの一番最初、出力より前に呼ぶ

// ログイン成功時
$_SESSION["user_id"] = 42;
$_SESSION["user_name"] = "田中";

// 別のページでも(session_start() を呼べば)同じ値が読める
echo "ようこそ、" . ($_SESSION["user_name"] ?? "ゲスト") . "さん\n";

ログアウトするときは $_SESSION を空にし、セッション自体も破棄します。

<?php
session_start();
$_SESSION = [];         // セッションのデータを空にする
session_destroy();      // サーバー側のセッションを破棄する

クッキーとセッションの関係をまとめると、次のようになります。

sequenceDiagram
    participant B as ブラウザ
    participant S as サーバー
    B->>S: ログイン情報を送信
    S->>S: セッションIDを発行しデータを保存
    S-->>B: Set-Cookie: セッションID
    B->>S: 次のリクエスト(クッキーを自動添付)
    S->>S: セッションIDからデータを検索
    S-->>B: ログイン済みとして応答

セキュリティ上、ログイン成功時には session_regenerate_id(true) でセッションIDを発行し直す(セッション固定化攻撃への対策)、クッキーには HttpOnlyJavaScriptから読めない)・SecureHTTPS限定)といった属性を付ける、といった対策が実務では重要です。

演習

(読み物のため自動判定はありません)手元にPHP環境があれば、login.phpsession_start() して $_SESSION["user"] に名前を保存し、mypage.php という別ファイルでも session_start() して同じ値が読み出せることを確認してみましょう。ブラウザの開発者ツールで、クッキーに PHPSESSID が保存されている様子も見てみると理解が深まります。