Kodokon kodokon.com

セッションとクッキー:ログインとショッピングカート

訪問者をページからページへと覚えておきましょう。安全なログイン、セッションを使ったショッピングカート、そして正しく保護されたクッキーです。

10 分 · 3 問

このレッスンを Kodokon で開く

HTTPは何も覚えていません。各リクエストは、前のものとのつながりを持たず、まっさらな状態でやってきます。セッションはこの問題を解決します。session_start()は、クッキーで伝えられる一意な識別子と、$_SESSIONを通じてアクセスできるサーバー側の保存領域とを、訪問者に結びつけます。session_start()は、あらゆる出力の前に、関係する各ページの一番上で呼び出しましょう。

PHP
<?php

declare(strict_types=1);

session_start();

$storedHash = password_hash('secret123', PASSWORD_DEFAULT);
$password = $_POST['password'] ?? '';

if (password_verify($password, $storedHash)) {
    session_regenerate_id(true);
    $_SESSION['user_id'] = 42;
    header('Location: /account.php');
    exit;
}

echo "Invalid credentials.";
login.php:実際には、ハッシュはあなたのデータベースから来る。

ページを保護するとは、つまりセッションの中にユーザーがいるかを確認し、いなければリダイレクトすることです。セッションはショッピングカートの理想的な一時保存場所としても役立ちます。product id => quantityという連想配列がページからページへと生き延びるのです。

PHP
<?php

declare(strict_types=1);

session_start();

if (!isset($_SESSION['user_id'])) {
    header('Location: /login.php');
    exit;
}

$_SESSION['cart'] ??= [];

$productId = filter_input(
    INPUT_POST,
    'product_id',
    FILTER_VALIDATE_INT
);

if (is_int($productId)) {
    $qty = $_SESSION['cart'][$productId] ?? 0;
    $_SESSION['cart'][$productId] = $qty + 1;
}

$count = array_sum($_SESSION['cart']);
echo "Cart: " . $count . " item(s)";
cart.php:保護されたページと、セッションに保存されたカート。

一方でクッキーはユーザーのデバイス上に存在し、ブラウザを閉じても生き延びます。テーマや言語の設定にぴったりです。PHP 7.3以降、setcookie()はオプションの配列を受け取ります。secure(HTTPSのみ)、httponly(JavaScriptから見えない)、そしてsamesite(他のサイトからの送信を制限する)を求めましょう。

PHP
<?php

setcookie('theme', 'dark', [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

$theme = $_COOKIE['theme'] ?? 'light';
echo "Active theme: " . $theme;
適切なフラグを付けた、三十日間有効な設定クッキー。

ログアウトは、ログインと同じくらい丁寧に行わなければなりません。$_SESSIONを空にし、サーバー側のセッションを破棄し、識別子を運んでいたクッキーを失効させましょう。

PHP
<?php

session_start();

$_SESSION = [];
session_destroy();

setcookie(session_name(), '', time() - 3600, '/');

header('Location: /login.php');
exit;
logout.php:跡を残さない、完全なログアウト。

理解度チェック

このレッスンの要点をしっかり覚えているか確認しましょう。

  1. PHPセッションのデータはどこに保存されますか?
    • ユーザーのデバイス上のクッキーの中
    • サーバー上。ブラウザはクッキーの中に識別子だけを保持する
    • 各ページのURLの中
    • ブラウザのlocalStorageの中
  2. ログインが成功した直後に、なぜsession_regenerate_id(true)を呼び出すのですか?
    • セッション固定化を防ぐため。ログイン前に知られていた識別子が使えなくなる
    • セッションクッキーの寿命を延ばすため
    • 古いカートのデータを消すため
  3. クッキーのhttponlyオプションは何をしますか?
    • クッキーの中身を暗号化する
    • クッキーを安全でない接続に限定する
    • クッキーをページのJavaScriptからアクセスできなくし、XSSによる盗難を抑える