こんにちは、CTOの奥田です。
先日ウィルスタイルは15期を迎えました。
私も11月で入社して6年になります。
大好きな神戸でお仕事ができるという喜びやこのお仕事を通じて様々な経験が出来たこと、また沢山の仲間と出会えたこと非常に嬉しく思います。
これからもウィルスタイルをどうぞよろしくお願い致します。
さておよそ1年ぶりにPHP入門です。
前回は「【PHP入門】GETとPOST Vol.8【初心者向け】」というタイトルでGETとPOSTについてご説明しました。
今回はCookieとセッションについて出来るだけわかりやすくご説明出来ればと思います。
Table of contents
Cookieとセッション
Cookieもセッションもユーザーを識別するためにデータを保持するものだと思っていただければわかりやすいかと思います。
例えば自動ログイン機能やフォームの一連の処理を認識するために用いられ、Webアプリケーションを構築する際には欠かせない機能となっております。
2つの大きな違いはCookieはブラウザに保存され、セッションはサーバーに保存されるという点です。
Cookieとは
Cookieとはクライアント側に保存されるデータです。
Cookieを使用する際、サーバー側からはSet-Cookieという名前のフィールドをHTTPヘッダに載せ、レスポンスを返します。
レスポンスを受け取ったクライアントはCookieをブラウザに保存します。それ以降のリクエストには受け取ったCookieをそのままリクエストするようになります。
またCookieには有効期限を設定でき、有効期限が切れたCookieは消滅し、リクエストに載らなくなります。
Cookieの使い方
Cookieはsetcookie()で保存できます。
setcookieは内部でSet-Cookieヘッダーのレスポンスを返しています。
setcookie( name, value, expires, path, domain, secure, httponly, options);
引数の説明は以下です。
引数 | 説明 |
---|---|
name | クッキーの名前。 |
value | クッキーの値。この値はクライアントのコンピュータに保存されますので、 重要な情報は格納しないでください。 name が ‘cookiename’ だとすると、 その値は $_COOKIE[‘cookiename’] で取得することができます。 |
expires | クッキーの有効期限。これは Unix タイムスタンプなので Epoch(1970年1月1日)からの経過秒数となります。 time() または mktime() 関数により 返された現在のUNIX標準時に、期限としたい必要な秒数を加算したものを 利用することができるでしょう。 time()+60*60*24*30 はクッキーの有効期限を 30日後にセットします。 0を設定したり省略したりした場合は、クッキーはセッションの最後 (つまりブラウザを閉じるとき) が有効期限となります。 |
path | サーバー上での、クッキーを有効としたいパス ‘/’ をセットすると、クッキーは domain 配下の全てで有効となります。 ‘/foo/’ をセットすると、クッキーは /foo/ ディレクトリとそのサブディレクトリ配下 (例えば /foo/bar/) で有効となります。 デフォルト値は、クッキーがセットされたときのカレントディレクトリです。 |
domain | クッキーが有効な (サブ) ドメイン。これを ‘www.example.com’ などのサブドメインに設定すると、 www サブドメインおよびそれ自身のすべてのサブドメイン (w2.www.example.com など) でクッキーが使えるようになります。 サブドメインを含むドメイン全体でクッキーを有効にしたければ、そのドメイン自体 (この場合は ‘example.com’) を設定します。 |
secure | クライアントからのセキュアな HTTPS 接続の場合にのみクッキーが送信されるようにします。 TRUE を設定すると、セキュアな接続が存在する場合にのみクッキーを設定します。 サーバー側では、このようにセキュアな接続の場合にのみクッキーを送信するという処理は プログラマの責任で行うことになります (たとえば $_SERVER[“HTTPS”] の内容を使用します)。 |
httponly | TRUE を設定すると、HTTP を通してのみクッキーにアクセスできるようになります。 つまり、JavaScript のようなスクリプト言語からはアクセスできなくなるということです。 この設定を使用すると、XSS 攻撃によって ID を盗まれる危険性を減らせる (が、すべてのブラウザがこの設定をサポートしているというわけではありません) と言われていますが、これはしばしば議論の対象となります。 PHP 5.2.0 で追加されました。 TRUE あるいは FALSE で指定します。 |
options | expires, path, domain, secure, httponly および samesite のうちから、任意のキーを設定可能な連想配列(array)です。 これら以外のキーが存在する場合、E_WARNING レベルの警告が発生します。 値については、キーと同じ名前のパラメーターで説明した意味と同じです。 samesite 要素の値は、 None, Lax または Strict です。 上記で許されているオプションのうち、与えられなかったものについては、 デフォルト値は明示的にパラメータを与えた場合のデフォルト値と同じです。 samesite 要素が省略された場合は、SameSite クッキー属性は設定されません。 |
value以下は省略可能なので以下のように簡潔に書くことが出来ます。
setcookie('user', "Mineo Okuda", time()+60*60*24*30); // ※例として有効期限を30日に設定しています。
複数の値を格納したい場合はjson_encode()をして格納します。
setcookie('user', json_encode(["name" => "Mineo Okuda" ,"age" => 34 ]));
また、Set-Cookieを送信することでスーパーグローバル変数$_COOKIEが使用可能になります。
var_dump( json_decode($_COOKIE["user"] ,true ) ); // array(2) { ["name"]=> string(11) "Mineo Okuda" ["age"]=> int(34) }
Cookieを削除するには空の値をセットします。
setcookie('user', "");
Cookieの上限
1つのドメインに対して、作成できるCookieの数とサイズには上限があります。
ブラウザごとに異なりますが下記のような数やサイズを超すようなデータを取り扱う際は注意が必要です。
Cookieの全容量 | 300個(個数を超えると古いCookieから削除) |
---|---|
1つのドメインでの制限数 | 20個(個数を超えると保存できない。ブラウザによって上限が異なる) |
1つのCookieの容量 | 4096byte |
セッションとは
セッションとは一連の処理の始まりから終わりまでを意味しています。
Webサイトに訪れたユーザーは1回のアクセスに対し、複数のリクエストを行います。
例えばECサイトであれば [商品の検索 → 決済情報の入力 → 確認 → 購入] これらは1セッションですがサーバーへのリクエストは複数となります。
この一連の流れを取り扱えるというものがセッションです。
仕組みとしては、先程ご説明したCookieを利用します。Cookieに一意な値を格納し、それに付随したセッション情報をサーバー側に保持し、取り出したり保存したりできるというものです。
以下のようにセッションを開始するとPHPSESSIDという名前でセッションIDが入っています。
セッションの保存先
セッションの保存先はphp.iniのsession.save_pathによって指定が可能です。
session.save_path
現在の保存先の確認は以下のように出力することで確認ができます。
var_dump(session_save_path()); // string(20) "/var/lib/php/session"
また、セッションをデータベースへ保存することも可能です。また、PHPフレームワークのLaravelでは設定ファイルを書き換えるだけでセッションの保存先を変更できます。
PHPにおけるセッション管理について
セッションの使い方
セッションはsession_start()を実行することで開始できます。
session_start();
また、session_startは必ずセッションが開始されていない状態でないとエラーとなってしまうので以下のように記述します。
if(!isset($_SESSION)){ session_start(); }
これでセッションが使えるようになります。スーパーグローバル変数$_SESSIONに連想配列で値を入れることで一時的にデータを保持できます。
$_SESSION["username"] = "Mineo Okuda"; // array(1) { ["username"]=> string(11) "Mineo Okuda" }
連想配列を入れることもできます。
$_SESSION["user"] = [ "name" => "Mineo Okuda" , "age" => 34 ]; // array(1) { ["user"]=> array(2) { ["name"]=> string(11) "Mineo Okuda" ["age"]=> int(34) } }
特定のセッションを削除する方法は以下のようにunset()するだけです。
unset($_SESSION['name']);
セッションの有効期限
セッションの有効期限はphp.iniファイル内の記述を変えることで変更が可能です。
session.gc_maxlifetime = 1440 // デフォルトでは1440秒(24分)となっています。
デフォルトでは最終アクセスから数えて24分後に削除されます。
ただ、24分後に確実に削除されるわけではなく、有効期限が過ぎたセッションファイルは、1000回に1回の確率で削除されるという仕組みになっています。
セッションを破棄したい場合は以下のようにします。
$_SESSIONを空にしてsession_destory()をするだけではCookieが削除されておらず、先述の通りセッションファイルも削除されていないので取得できてしまいます。
なのでCookieも同時に削除することで確実に破棄することが出来ます。
$_SESSION = []; setcookie(session_name(), '', time()-1, '/'); session_destroy();
さいごに
Cookieとセッションについてご説明いたしました。
Cookieやセッションは非常に便利であり、ユーザーとのインタラクティブなコンテンツ作りには欠かせないものですが、ユーザーの情報を取り扱うので非常に注意が必要です。
実際にセッションには以下のような脆弱性があります。Webアプリケーションを作る上では、このような脆弱性をしっかりと理解して、セキュリティ対策をする必要があります。
- セッションハイジャック(セッションIDを盗んでなりすまし)
- セッションフィクセーション(セッションIDを強制する)
- クロスサイトリクエストフォージェリ(操作の強要)