質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.59%

$_COOKIEと$SESSIONに違いや利用法につきまして

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,671

SugiuraY

score 249

そもそもCOOKIEとSESSIONが理解できてなかったため、qitaの記事を参考にしながら理解を深めようと思っていたのですが、以下の点で概ね理解があっているかを確認したく投稿させていただきました。

 1) session_start()によるID発行

クライアントがリクエストし、session_start()によって、サーバー側はセッションidが未発行の場合には、セッションidを発行する。この時クライアントサイドではCOOKIEにデフォルトでsession_nameを変更しない場合、名前:値としてPHPSSID:xxxxxxxxxが保存されるとともに、サーバー側ではセッションファイルが作成されるとともに、COOKIEのPHPSSID:xxxxxxxxxと紐付けがされる。

 2)一連の処理に置けるデータの保存やチェック

クライアント側ではCOOKIEは偽装可能(ユーザーが好きに値を変えて変更できてしまう)ため、COOKIEに保存されたセッションIDによりサーバー側でデータをチェックすることやセッション間のデータの保存をする必要がある。
最も重要な点を言い換えれば、ステートレスを前提としたhttp通信の環境下で、リスクに少ないサーバー側でデータを保存等をする。またそれを適切にやりとりするためクライアント側ではCOOKIEによりセッションIDだけを持たせ、サーバー側ではこのIDに紐づく情報をセッションファイル内に保存させる仕組みとなっている

 3) セッションIDが既に発行でsession_start()が実行される場合

セッションidが既に発行されているおり、session_start()がサーバー側で実行される場合には、既存のセッションを再開する。(マニュアル)つまり、クライアントから送られてきたリクエストのCOOKIEに保存されているセッションIDを取得すし、サーバー側でそれに紐づくセッションファイルを呼び出し、情報を呼び起こす。(例えば、echo $_SESSION['name']などでセッションファイルに保存された連想配列の添字'name'に値にページ遷移後でもアクセスすることができる)

これらの理解があっていることを前提とした場合ですが、

ユーザーのページ遷移に伴って、一連で処理させたい場合、$_SESSIONは上記で理解できるのですが、$_COOKIEの使いどころがいまいちピンときません。$_COOKIEに保存されるセッション名はsession_name()で変更するでしょうが、開発側でCOOKIEのexpireやmax-ageを調整して期間を短くして、セキュアに運用したい等の目的で$_COOKIEは使われるのでしょうか?

 B) 一連処理を実現するためのSESSIONやCOOKIEを利用する場合のセキュリティ上の対策

これは記事に載っていないですが例えば(セッションハイジャック対策ですが)、

  • $_COOKIEや$_SESSIONの有効期間を短くしたりdestroyすることにより、みだりに長く情報を保存しない。
  • session_regenerate_id();で遷移の都度idを変更して、cookie側とセッションファイル側のidを更新する
  • session名をsession_nameによりPHPSSIDから変更する

等があげられたりしますが、実務上、さらに注意すべき点や対策に不足がある点はございますでしょうか、また正直最後のセッション名の変更はセキュリティ上、あまり意味がないきがするのですが、どういった理由でPHPSSIDから変更すべきなのでしょう?

以下のvar_dump($_COOKIE['amturing']);をした場合、xxxxxxxxが返され、これはsession_regenerate_id();される前のidであり、その後に取得しているCOOKIE側のセッションIDの値であるためなぜ、yyyyyyyyが取得されないのかがわかりません。実際にGoogle ChromeのディベロッパツールのApplicationのCOOKIEではyyyyyyyyが表示されております。

session_name("amturing");
session_start();
$oldid=session_id();
session_regenerate_id();
$newid=session_id();

var_dump($oldid);//xxxxxxxx
echo "<br>";
var_dump($newid);//yyyyyyyy
var_dump($_COOKIE['amturing']);//xxxxxxxx

長文となり、申し訳御座いませんが
よろしくお願い申し上げます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+2

A)

まずクッキーとセッションは別のものだということを理解しましょう。

セッションIDをブラウザとやりとりするのにcookieの仕組みに乗っかるのが便利だからよく使われていますが、cookieの用途はそれだけに限りませんし、セッションIDのやり取りにクッキー以外のものを使ってもかまいません。

C)

$_COOKIEはリクエストのcookieヘッダで送られてきた値を保持するものです。session_regenerate_id()で新たにセッションidが作られますが、$_COOKIEがその場で新しい値に書き換えられるわけではなく、レスポンスのset-cookieヘッダでブラウザ側に送られます。そのレスポンスを受けとった後のリクエストで新しいセッションidがcookieヘッダで送られてくるので、そのリクエストを処理するために新たに起動されたPHPプログラムの中で$_COOKIEが新しい値になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/07 17:27

    ご回答頂き有難うございます。$_COOKIEが書き換えられるタイミングについて誤認があったようです。
    勉強になりました。

    キャンセル

+1

$_COOKEと$_SESSIONの大きな違いは

値をブラウザ側に保持するか、サーバに保持するかの違いです。
ただし、$_SESSIONは、$_COOKIEを一つ利用します。
それは、サーバ側のセッションデータを特定する為に
SessionIDを$_COOKEに入れてます。

また、セッションID以外の、$_COOKEは、セッションとは一切無関係です。

ブラウザ側に、値を保持するのは、現実的には、セキュリティの問題を起こしますので、$_SESSIONを利用するのが賢明です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/17 08:35

    コメントありがとうございます。
    ご教示頂きました内容については感覚的には理解することができました。
    今、試しに自分が運営するサイトでPHPグローバル変数の$_COOKIEをdumpする処理をしてみたところ、
    連想配列でブラウザが認識している['session name']=>"session id(value)"のみが出力されました。

    ご教示いただいた内容と、このことに重ねて考えると、PHPのグローバル関数である、$_COOKIEとは
    1) ブラウザに保持されたデータをサーバー側で識別するためにブラウザのクッキー情報にアクセスする必要があり
    2) $_COOKIEによりこれを取得することができる。
    3) サーバー側でセッション処理をしたい場合には、$_COOKIEに格納されるセッションIDを紐付けることにより実現できるが、それはセッション処理の一つの手段にすぎない。
    4) また$_COOKIEはセッションIDのみを連想配列で格納するグローバル変数である。
    との理解でしょうか?

    また、$_COOKIEは私の感覚ではブラウザ側のクッキー情報に直接アクセスしてセッションIDを取得しに行っていると理解しているのですが正しいでしょうか?
    ”ただし、$_SESSIONは、$_COOKIEを一つ利用します。”
    という表現からサーバー側の$_SESSIONを通してセッションIDを間接的に取得しているようにも読み取れたのですが、具体的に調べてもわからなかったため。。
    セッション処理が(1)ブラウザのクッキー情報(name=value)と(2)サーバー側($_SESSION)のセッションファイルのsession idを紐付けることにより実現されるブラウザーサーバー間の処理であると考えていたのですが、とするとサーバー側の$_COOKIEは何の意味があるのだろうという点が出発点だったのですが、サーバー側もブラウザから取得したクッキー情報のSessionIDが$_COOKIEに取得されて、サーバー側で$_COOKIEと$_SESSIONが紐付けされるならそういった役割があるかと思ったのですが、そうでなければ、意味がないスーパーグローバル関数では、、と思っておりました。

    不案内でありわかりづらくて本当に申し訳ございません。

    キャンセル

checkベストアンサー

0

(1)~(3)の内容の理解について

概ね、記載されている理解で正しいと思います。
 

まず、sessionとcookieはそもそも使いどころが違うもの、というところを理解してください(同じような趣旨で使うことも可能ではありますが……)。

■cookie
保存場所はユーザーのPC内(=1万人の利用者がいるサイトの場合でも、1人分のデータしか管理しない)。
多少改ざんされたとしても問題はないデータを保存する。長期記憶向きだが、短期記憶に使うこともある。
用途例:セッションID(※IDだけです)、サイトの閲覧履歴
  
■session
保存場所はサーバー内(=1万人の利用者がいるサイトの場合、1万人分のデータをサーバーで管理する必要がある)。
改ざんされると困るデータを保存する。短期記憶向き。
用途例:登録機能の画面遷移中のデータ保持(入力画面→確認画面→完了画面)、ログインユーザーの情報
 

 B) 一連処理を実現するためのSESSIONやCOOKIEを利用する場合のセキュリティ上の対策

「また正直最後のセッション名の変更はセキュリティ上、あまり意味がないきがするのですが、どういった理由でPHPSSIDから変更すべきなのでしょう?」とありますが、これは、COOKIE情報を書き換えることによるセッションハイジャックを防ぐための方策ですね。※細かい話ですが、セッション名の変更ではなくセッションID名の変更かと思います。

悪意のある人が「どこのサイトでもいいから、とにかくセッション情報をハイジャックしてみよう」と思った時の方法の1つに「ドメインリストを作って、それに対してPHPSSIDというキーのCookieを作ってアクセスを試行する」という方法があります(詳細は割愛します)。
その時、セッションIDがPHPSSIDでなければ、(そもそもセッションIDが違うので)セッションがハイジャックされることはありません。

なお、この変更は「(どこでも良い、ではなく)このサイトのセッションをハイジャックしてやろう」という攻撃の場合に対しては、さほど大きな効果は無いと思います(攻撃者は、Cookie上に格納されているデータを見て、そのサイトでのセッションID名を推測することが可能だと思われるため。PHPSSIDのままにしておくよりは多少マシ、という程度かと)。

(他の回答者さんの回答と重複してしまいますが) $_COOKIE は、その処理に遷移した時点で、ユーザーのブラウザが持っていたクッキー情報を保管する場所です。
クッキー情報を書き換えた処理の中では、新しい値に変わっていないものだと思いますが……。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/07 17:26

    詳細にコメント有難うございます。
    昨日帰国したため、ご返信遅くなり申し訳ございません。
    少し未だ、クッキーとセッションの違いが分かっていない部分もあると思いますが
    詳細は勉強してみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る