クッキー・セッションとは?

この記事では、現代のウェブ開発に欠かせない技術であるセッションとクッキーの違いについて解説します。セッションとクッキーの違いを理解し、セキュアなウェブサイトを作る上で知っておくべき内容を、分かりやすくまとめています。読み終えた頃には、セッションとクッキーの理解度がグッと高まります。

クッキーってなに?

OZ
OZ

プロ太先生、ウェブサイトで「クッキーを許可しますか?」ってよく出てくるの、あれって何なんですか?

いい質問ですね!クッキーは、ウェブサイトがユーザーのデータを一時的に保存するための仕組みです。簡単に言うと、ウェブサイトとOZ君のパソコンの間で小さなメモのやり取りをする感じですね。

メモ??たとえば、どんな情報を書いておくんですか?

例えば、ログインしたことをメモして覚えておいて、次にサイトのページを開いたときも自動でログイン状態を保つとか、ショッピングカートの中身をメモしておいて保持することができるんです。ちなみに、みんなが大好きなYouTubeのおすすめ動画を表示するのもクッキーの仕組みのおかげなんですよ。

HTTPという通信の仕組みは、基本的に**ステートレス(無状態)**です。つまり、何もしなければ、サーバーは1回の通信ごとに、誰がアクセスしているのかを忘れてしまいます。そこで、クッキーを使ってユーザーを識別することができます。クッキーはサーバーからユーザーのブラウザに送られます。そして、ブラウザがそのクッキーを保存して、次に同じサイトを開いたときに再びサーバーに送り返します。こうすることで、サーバー側は「あ、このユーザーは前に来たことがある!」って認識できる仕組みです。

クッキーの読み取りと削除

ちょっと難しそうやな〜。実際に、どんな風に使うか見せてもらえますか?

もちろんです!じゃあ、まずはJavaScriptでクッキーをセットするコードを見てみましょう!

// クッキーをセットする
document.cookie = "username=OZ; path=/; max-age=3600";

へぇ〜、document.cookieってのがクッキーを扱うための方法なんですね。

そうです。このコードだと、usernameという名前のクッキーに’OZ’という値を書き込んでいます。そして、max-ageは3600秒、つまり、「1時間の間だけ有効」とクッキーに書き込んでいます。

クッキーの読み取りと削除

なるほど!じゃあ、このクッキーはどうやって読み取るんですか?僕のPCで見れますか?

読み取って確認するのも、簡単にできますよ。

// クッキーをコンソールに表示する
console.log(document.cookie);

へぇ〜なるほど!これを実行すると、保存されているクッキーが全部見れるんですね!画面の最後に、ちゃんとusername=OZがメモされてる!!

その通りです!そして、もしさっき書いたクッキーを削除したくなったら、下のようにmax-ageを0にセットすればOKです!期限を0にしているので、消えるわけですね。

// クッキーを削除する
document.cookie = "username=; path=/; max-age=0";

あっ、これは値を空にして期限をゼロにしてるんですね!なるほどな~。

クッキーの注意点

でも、これだけいろんな情報を保存してると、なんか怖くないですか?プライバシー的には大丈夫なんですか??

その通り!!!便利なクッキーですが、注意しなければいけないこともあります!特に、ユーザーのプライバシーを守るために、クッキーを使うときは注意が必要です。例えば、サイトによっては、クッキーを使ってユーザーの行動を追跡してメモする場合もあるんです。だから、法律でユーザーのプライバシーを守るためのルールが整えられています。特に、ヨーロッパのGDPR(一般データ保護規則)では、クッキーを使うときにはユーザーの同意が必要とされています。

あっ!!それで、“クッキーを許可しますか?”ってポップアップが画面に出るんですね。

そうです。なので、ユーザーにちゃんと説明して、必要なクッキーだけを使うようにすることが大事なんです。特に、追跡用クッキーという、広告表示を最適化するためのクッキーもあるんですが、こういうものは特に慎重に扱う必要があります。

PHPでのクッキー管理

先生!JavaScript以外でもクッキーを使えますか?例えば、PHPとか??

もちろんです!PHPでも簡単にクッキーを操作できますよ。こんな感じです。

// クッキーをセット
setcookie("username", "OZ", time() + 3600, "/", "", true, true);

setcookieの各引数の役割は以下の通りです。

  1. "username" – クッキーに記入する「キー」の名前
  2. "OZ" – 「キー」に保存するバリュー
  3. time() + 3600 – 有効期限の時間。現在時刻から1時間(3600秒)後
  4. "/" – クッキーが有効なパス。ここではサイト全体
  5. "" – ドメイン。空の場合はカレントドメイン
  6. true – HTTPのみ(JavaScript経由でアクセスできなくなる)
  7. true – セキュアクッキー(HTTPSでのみ送信される)

つまり、このコードは以下のように動作します。

  • ユーザー名”OZ”を持つクッキーを作成
  • クッキーの有効期限は1時間後
  • クッキーはサイト全体で有効
  • HTTPのみアクセス可能(JavaScriptからは読めない)
  • HTTPSでのみ送信される(セキュアクッキー)

これによりクッキーの安全性が高まり、ユーザーの個人情報を保護できるようになります。

PHPでクッキーに複数のキーとバリューを設定する場合は?

クッキーにPHPで複数のキーとバリューを設定するには、setcookieを複数回呼び出す必要があります。

例えば、ユーザー名とメールアドレスの2つのキーを設定する場合は以下のようになります。

setcookie("username", "OZ", time() + 3600, "/", "", true, true);
setcookie("email", "oz@example.com", time() + 3600, "/", "", true, true);

これにより、以下の2つのクッキーが設定されます。

  1. username=OZ
  2. email=oz@example.com

有効期限、パス、HTTPOnly、Secureの設定は両方のクッキーで同じになります。
(ちなみに、セキュリティーのことを考えて、クッキーには個人情報は保存しないようにしましょう)

PHPでのクッキーの取得・使用方法

クッキーを取得する際は、$_COOKIEスーパーグローバル変数を使って、それぞれのキーの値を取得できます。

echo $_COOKIE['username']; // OZ
echo $_COOKIE['email']; // oz@example.com

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

ちなみにクッキーとよく似たもので、セッションというものがあります。

セッション??なんですかそれ?これもメモなんですか?

セッションも、クッキーと同じくユーザーの情報を一時的に記憶するためのメモのようなものです。ただ、セッションは自分のパソコンのブラウザに保存するんではなくて、サーバー側に情報を保存するのが特徴なんです。
そして、クッキーはブラウザを閉じても残ることが多いんですが、セッションは、セキュリティーのこともあって、ユーザーがサイトを離れたりブラウザを閉じたときに削除されることが一般的です。ただし、セッションの有効期限はカスタマイズすることは可能です。

セッションを使ったコード例

実際にセッションを使ったコードを見せてもらえますか?

もちろん!じゃあ、今回はPHPでのセッション管理の基本を見ていきましょう!

// セッションを開始
session_start();

// ユーザー名をセッションに保存
// 実際は、フォームなどで入力した値をセッションに保存することが多い
$_SESSION['username'] = 'OZ';

// セッションからユーザー名を取得
echo 'ようこそ、' . $_SESSION['username'] . 'さん!';

これって、ユーザー名をサーバー側で保存して、あとで呼び出してるんですね!

そうです!この方法なら、ブラウザに直接データが残らないので、セキュリティ面でも安心なんです!

セッションとクッキーの併用—最強の組み合わせ

セッションとクッキーって一緒に使うこともできるんですか?

もちろんですよ。例えば、ユーザーがログインしたときにセッションでユーザー情報(個人情報)を管理し、クッキーでログイン状態を保持するようにすれば、サイトの使いやすさがアップします!

ログイン状態の管理コード例

// ユーザーがログインしたときにセッションとクッキーをセット
session_start();
$_SESSION['logged_in'] = true;
setcookie('user_session', session_id(), time() + 3600, "/");

このコードは、ユーザーがログインしたときにセッションとクッキーをセットするものです。
詳しく解説します。

  1. session_start();
    • PHPのセッション機能を開始します。
    • これにより、ユーザーのセッション情報を管理することができます。
  2. $_SESSION['logged_in'] = true;
    • ユーザーのログイン状態を true に設定します。
    • これで、ユーザーがログイン済みであることを判断できるようになります。
  3. setcookie('user_session', session_id(), time() + 3600, "/");
    • ユーザーのセッションIDをクッキーに保存します。
    • クッキーの名前は 'user_session' です。
    • クッキーの値は、現在のセッションIDです。session_id() で取得できます。
    • 有効期限は1時間(3600秒)後です。
    • クッキーのパスは '/' なので、サイト全体で有効になります。

この一連の処理によって、ユーザーのログイン状態が2つの方法で管理されます。

  1. セッションデータ: ユーザーがログイン済みであることを示すフラグ $_SESSION['logged_in']true に設定されます。
  2. クッキーデータ: ユーザーのセッションIDがクッキーに保存されます。

ログイン後のページ遷移では、これらのセッションデータとクッキーデータを使って、ユーザーの認証状態を確認することができます。

このような方法でセッションとクッキーを組み合わせることで、ユーザーの状態を効果的に管理できるようになります。セッションはサーバー側、クッキーはクライアント側で管理されるため、より安全性の高いアプリケーションを構築できます。

セッションIDとその管理の重要性

先生、セッションのイメージは湧いたけど、セッションIDって何ですか?

セッションIDは、サーバーがユーザーごとに割り当てる識別番号です。銀行の整理券と同じイメージです。ユーザーがアクセスするたびに、サーバーはそのIDを使ってどのセッションがどのユーザーのものかを区別しています。

なるほど。でも、もし誰かにこのセッションIDを盗まれたら、どうなりますか?

とても危険ですね!!それをセッションハイジャックって言うんです。だから、セキュアなサイトでは、HTTPS通信を使ったり、IPアドレスのチェックをしたりすることで防いでいます。

セッションハイジャックの具体例:盗まれるシナリオをイメージしてみよう!

じゃあ、銀行のサイトにアクセスするシーンを想像してみましょう。OZくんがログインした直後、銀行のサーバーからOZくんのパソコンに『この人はOZくん』と識別するセッションIDが送られます。

セッションIDはユーザーの身分証みたいなものなんですもんね!

そうです。そして、そのセッションIDが悪意のあるハッカーに盗まれると、OZ君のふりをしてログインできちゃいます。

ええ!?それは嫌や!!勝手にお金を引き出されたりしそう、、、
ちなみに、どうやって盗まれるんですか?

攻撃手法1:ネットワーク盗聴(スニッフィング)

まず一つ目の手法は、ネットワーク盗聴(スニッフィング)です。例えば、OZくんがカフェのフリーWi-Fiに接続して、銀行のサイトを開いたとします。

うん、公共のWi-Fiって便利ですよね。

でも、暗号化されていない通信だと、そのWi-Fiに接続しているハッカーが、やり取りされているセッションIDを盗み見ることができちゃうんです。

えーっ、じゃあ、あちこちでWi-Fiを使うのは危険なんですか?

そうですね。でも、こういう盗聴から守るためには、HTTPSの暗号化通信を使うのが有効なんです。

対策1:HTTPSを使うことで安全にする

HTTPHTTPS通信の違いは、しっかりと理解しておきましょう!

HTTP通信:
ユーザー → サーバー(通信がそのまま見えてしまう)

HTTPS通信:
ユーザー → 🔒 暗号化された通信 → サーバー(盗聴されても内容は読めない)

なるほど!HTTPSが付いているサイトなら、通信が暗号化されるんですね!

そうです。なので、オンラインショッピングや銀行のサイトでは、URLが「https://」で始まるかを必ず確認するようにしましょう!!

攻撃手法2:クロスサイトスクリプティング(XSS)

他にもセッションIDを盗む方法ってあるんですか?

まだあります!次は、クロスサイトスクリプティング(XSS)という手法を説明します。これは、悪意のあるスクリプトを仕込むことで、ユーザーのセッションIDを盗む方法になります。

XSSの攻撃シナリオ

  1. 悪意のあるリンクが、SNSやメールで送られてくる。
  2. OZくんが気づかずにそのリンクをクリック。
  3. サイト内に仕込まれたJavaScriptコードが実行され、OZくんのセッションIDが攻撃者のサーバーに送信される。

ええ!?じゃあ、クリックするリンクも気をつけないといけないんですね!

その通り!怪しいリンクには絶対に触れないことが大切ですし、XSSの対策としては、サイト運営者がHTMLやJavaScriptの入力をきちんとエスケープ処理することが何より必要です。

攻撃手法3:セッションフィクセーション攻撃

まだ他にも攻撃方法ってあるんですか?

もう一つ、セッションフィクセーション攻撃についても説明しておきますね。この攻撃では、ハッカーがあらかじめ用意したセッションIDを犠牲者に使わせます。

セッションフィクセーションの攻撃シナリオ

  1. ハッカーが、自分で発行したセッションIDをOZくんに送りつける。
  2. OZくんがそのIDを使ってサイトにログイン。
  3. ハッカーは、同じセッションIDを使ってOZくんのアカウントに不正アクセスする。

対策2:セッションIDの再生成

こうした攻撃を防ぐために、ログイン後にセッションIDを再生成することが推奨されているんです。

// ログイン後にセッションIDを再生成
session_regenerate_id(true);

なるほど!これで、ハッカーが用意したIDを使わせないようにするんですね!

そうです!!そして、最後に対策としてもう1つ紹介しておきます!それは、セッションタイムアウトを利用することです!

セッションタイムアウト?それってどういう仕組みなんですか?

なぜセッションタイムアウトが重要なのか?

タイムアウトがないと、例えば、カフェや図書館などの公共の場所で、ログインしっぱなしにして、他の人にPCやスマホを触られたとき、不正アクセスのリスクが高まります。

それは危険ですね、、、。銀行サイトとかがタイムアウトを使ってる理由が分かりました!

特に機密情報を扱うサイトでは、タイムアウトが不可欠ということを押させておきましょう!じゃあ、ついでにセッションタイムアウトを実装する方法をPHPで見ておきましょう。

<?php
session_start();  // セッションの開始

// タイムアウトの秒数(ここでは15分)
$timeout = 15 * 60; 

// 最後の活動時間を確認
if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity']) > $timeout) {
    // タイムアウトを超えた場合、セッションを破棄
    session_unset();  // セッション変数を全て削除
    session_destroy();  // セッションを完全に破棄
    echo "セッションがタイムアウトしました。再度ログインしてください。";
} else {
    // 最後の活動時間を更新
    $_SESSION['last_activity'] = time();
}

// セッションにデータを保存する例:普通はフォームなどで入力した値を保存する
$_SESSION['username'] = 'OZくん';
echo "ようこそ、" . $_SESSION['username'];
?>

コード解説:

  1. session_start():セッションを開始します。
  2. $timeout:タイムアウト時間を設定。ここでは15分に設定しています。
  3. 最後の活動時間をチェック:セッションのlast_activityを使い、現在の時刻との差を計算します。
  4. タイムアウト後の処理:時間が経過していたら、session_unset()session_destroy()でセッションを削除します。
  5. 活動時間の更新:最後の活動時間を**time()**で更新します。

15分経ったら自動的にログアウトする仕組みなんですね!!これなら安全そうです!

こうすることで、長時間使われていないセッションが残らないようにできるんです!

他にもセッションのセキュリティー対策の例を紹介しておきますね。

セッションのセキュリティ対策の例

  1. HTTPSの使用
      - HTTPSで暗号化された通信を使えば、セッションIDが盗まれるリスクを減らせる。
  2. IPアドレスのチェック
      - セッションIDと一緒にIPアドレスも確認し、異なるIPからのアクセスをブロックする。
  3. セッションIDの定期的な再生成
      - ログイン後や特定のアクション後に、セッションIDを再生成することで盗難を防ぐ。

PHPでセッションIDを再生成する例

// セッション開始
session_start();

// セッションIDを再生成
session_regenerate_id(true);

このsession_regenerate_id(true)を使うことで、セッションIDを定期的に変更できるので、セッションハイジャックを防ぎやすくなるんです。

セッションの削除と終了方法

先生、もしユーザーがログアウトしたときは、どうやってセッションを終了させるんですか?

セッションの終了はとても大切なことですね。ログアウト時にセッションをきれいに削除することで、他の人がそのセッションを再利用するのを防ぎます。

PHPでセッションを完全に削除する例

// セッションを開始
session_start();

// 全てのセッション変数を削除
$_SESSION = [];

// セッションクッキーを削除
if (ini_get('session.use_cookies')) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}

// セッションを破棄
session_destroy();

echo 'セッションが終了しました。';

へ〜!!これで、ログアウト時にきれいにセッションが消えるんですね!

クッキーとセッションの使い分け—実践のポイント

先生、結局のところ、クッキーとセッションってどう使い分けるべきなんですか?

大切なのは、どんな情報を保存するかで使い分けることですね。

  • クッキーは、ユーザーの利便性を向上するための設定(例:テーマカラー、言語設定など)に使う。
  • セッションは、セキュリティが重要なログイン情報や一時的な操作(例:買い物かごの中身、銀行取引の確認など)に使う。

じゃあ、基本は、セキュリティが大事なところはセッションで、そうじゃないところはクッキーで管理すれば良いんですね!

まとめ

そうですね!クッキーとセッションをうまく使い分けることが、快適で安全なウェブサイト作りの鍵になります!!しっかりと理解して扱いましょう!!

  • クッキー:ユーザーの端末に保存し、サイトの利便性を向上させるもの
  • セッション:サーバー側で管理し、短期間の安全な操作をサポートするもの
  • セッションIDの管理:定期的に再生成し、HTTPS通信を使って盗難を防ぐ

クッキーとセッションは、現代のウェブ開発には欠かせない技術です。ユーザーの利便性とセキュリティを両立させるために、これらの仕組みを正しく理解し、適切に使いこなしましょう!