キャッシュ( Cache )、セッション( Session )、ブラウザに保存される Cookie 、Web Storage( Local Storage 、 Session Storage )、 IndexedDB について、聞いたことはあるけどそれぞれの違いを知らないという方もいるのではないでしょうか。
これらの仕組みは一度調べると個々の違いは理解できると思いますが、どのように違うのかと考えるとわかりにくい点があると思います。
また、サーバ以外のデータ保管場所を検討したいが最適な仕組みはどれは迷うこともあると思います。
今回はキャッシュ(Cache)、セッション(Session)、クッキー(Cookie)、Web Storage(Local Storage、Session Storage)、IndexedDBはそれぞれどのように異なるのか紹介します。本記事を読むことで、それぞれの違いがわかったうえでどれを使用するのが最適か選択できるようになるはずです。
各データ保管のおおまかな違い
サーバーからブラウザまでの経路が以下のような場合、Cache・Session・Cookie・WebStorage・IndexedDBのデータ格納場所は以下のようになります。
データ保管場所のほかにも「格納されるデータ」「操作元」「有効期限」もそれぞれ異なります。
Cache | Session | Cookie | WebStorage | IndexedDB | |
---|---|---|---|---|---|
格納場所 | サーバ以外 | サーバ内 | ブラウザ内 | ブラウザ内 | ブラウザ内 |
格納データ | ファイル | キーバリューデータ | キーバリューデータ | キーバリューデータ | キーバリューデータ |
有効期限 | あり(TTLにより設定) | あり(言語の設定による) | あり(Httpヘッダにより指定) | LocalStorageかSessionStorageかにより異なる | なし |
操作元 | インフラ設定・HTTPヘッダ | サーバサイド言語 | サーバサイド言語・javascript | javascript | javascript |
これらの違いにより、使用される用途も変わってきます。
用途・概要 | |
---|---|
Cache | 主にCDNキャッシュやブラウザキャッシュがあり、コンテンツをサーバ外に保管することで高速にコンテンツの受け渡しが可能となるためサイトパフォーマンスが向上したり、PWAではオフラインで使用できるようにする |
Session | 一連のアクセスに関わる情報をサーバーに保管する |
Cookie・WebStorage・IndexedDB | ブラウザにデータを保管し、サーバに送信したりjavascriptで操作して使用する |
Cacheは他と異なりコンテンツを格納するという特性からサイトの高速表示やオフライン利用に用いられ、データを保管するSession・Cookie・WebStorage・IndexedDBとは用途が大きく異なります。
SessionはSessionIDをCookieに保管することにより、SessionIDに紐づいたデータをサーバ上で保管します。
Cookie・Webstorage・IndexedDBはキーバリューデータをブラウザ上で保管するという点が非常に似ています。
こちらの違いについては後述にてさらに深堀して説明します。
Cookie・WebStorage・IndexedDBの違い
いままでWebStorageという書き方をしていましたが、WebStorageにはLocalStorageとSessionStorageの2つがありそれぞれ特徴が異なります。そこで、Cookie・LocalStorage・SessionStorage・IndexedDBの違いについて紹介します。
比較サマリ
Cookie | LocalStorage | SessionStorage | IndexedDB | |
---|---|---|---|---|
接続元 | 設定により接続元の絞り込みが可能 | 同一オリジンのみ | 同一オリジンのみ | 同一オリジンのみ |
別タブ・別ウィンドウ | 可能 | 可能 | 不可能 | 可能 |
データサイズ | 4kB | 5MB | 5MB | 1GB以上 |
データ送信 | 毎回 | 都度 | 都度 | 都度 |
処理 | 同期処理 | 同期処理 | 同期処理 | 非同期処理 |
トランザクション | なし | なし | なし | あり |
さらされる脅威 | CSRF | XSS | XSS | XSS |
それぞれの違いを一覧にまとめると上記のようになります。それぞれの違いについて以下でコメントしていきます。
PWAについては以下に詳細をまとめています。
[接続元]Cookieはある程度設定可能、WebStorage・IndexedDBは同一オリジンに限られる
Cookieの接続元設定
Cookieはデータのアクセス元をある程度自身で指定できます。CookieはHttpヘッダで格納するデータと合わせて接続元に関わる設定を記述できます。
Domain 属性
通常cookieは同一ドメインのみ接続を許可します。ただし、サブドメインにも許可したい場合はDomain属性を指定することができます。
Set-Cookie: [cookie-name]=[cookie-value]; Domain=[example.comなど];
上記の例では、www.example.comやsub.example.comもCookieを受信することができます。
Path属性
URLに特定のパスを含む場合のみCookieの受信を許可するように設定することができます。
Set-Cookie: [cookie-name]=[cookie-value]; Path=[/abcなど];
この場合、/abc/xyzなどのパスにも許可されます。
SameSite 属性
SameSite属性では「Strict:同一オリジンのみ許可する」、「Lax:同一オリジンかつ外部リンクを無効」、「None:オリジンが異なっても可」といった設定が可能です。
Set-Cookie: [cookie-name]=[cookie-value]; SameSite=[Strictなど];
LocalStorage・SessionStorage・IndexedDBの接続元
LocalStorage・SessionStorage・IndexedDBは「ドメイン」「プロトコル」「ポート」がすべて同一の場合にデータアクセスが可能です。例えば、「https://aaa.com」のアクセスで作成したデータは「http://aaa.com」からアクセスすることはできませんし、「https://aaa.com:8080」からアクセスすることもできません。
別タブで使用できるか
SessionStorageのみ(同じサイトを開いた)別タブからアクセスすることができません。
[データ]Cookieは小さいデータに向き、IndexedDBは大きなデータに向いている
Cookie・LocalStorage・SessionStorage・IndexedDBはそれぞれ格納できるデータサイズが異なります。
Cookieは4kBまで、LocalStorageとSessionStorageは5MBまで、IndexedDBはブラウザの仕様により格納できるデータサイズは異なりますがおよそ1GB以上は格納できます。また、Cookie・LocalStorage・IndexedDBはブラウザやタブを消してもデータが残る一方、SessionStorageはブラウザやタブを消すとデータは消えます。
LocalStorage・IndexedDBは有効期限がないため、明示的に消さない限りデータは残り続けるということになります。
クッキーが大量になれば毎回すべてデータが送信されるために重いサイトになってしまいます。
[処理]IndexedDBは非同期処理かつトランザクション処理がある
IndexedDBは非同期処理であるため、大量のデータを格納する際に処理を待たず次の処理を行えるというメリットがあります。
そのため、大容量データなどを保存する場合はIndexedDBが向いています。
また、IndexedDBはトランザクションがあります。一連のデータ格納処理が「すべて完了」するか「一部失敗する場合はすべて格納しない」という処理ができます。
[さらされる脅威]CookieはCSRF、WebStrorage・IndexedDBはXSSの対策が必要
Cookie・LocalStorage・SessionStorage・IndexedDBのようにブラウザにデータが保存されるものについてはデータがどのような脅威にさらされるか考える必要があり、それによってどの仕組みを使うのがベストか判断します。CookieはjavascriptによるXSS対策が可能
XSS(クロスサイトスクリプティング)は他者から悪意のあるスクリプトを実行されることでユーザーが意図しない挙動を引き起こす攻撃であり、javascriptで攻撃されることが多いです。
例えば、javascriptでCookie情報を外部に送られてしまえば、Cookieに格納されている情報(例えばSessionIDなど)を奪われてしまいます。
このような攻撃に対してCookieにhttponly属性を付与することで対策できます。httponly属性があるCookieはスクリプトから操作ができなくなります。また、CookieはSecure属性をつけることでhttps通信のみcookieを送信するように設定可能です。
CookieはCSRFの対策が必要
CSRF(クロスサイトリクエストフォージェリ)は外部サイトによってユーザが意図しない動作を引き起こす攻撃です。
例えば、Twitterにログインした状態で別タブからのTwitterで特定の投稿をするような仕組みが埋め込まれた悪意あるサイトにアクセスした場合、Twitterにユーザーが意図しない投稿がされてしまうというような攻撃です。
(※ 実際にはTwitterはCSRF対策済みでありこのようなことは起きません。)
これは「Cookieはすべての情報を毎回送信される」という性質を持つためです。
SessionIDのみで検証されているサイトの場合、たとえ他者から埋め込まれた意図しない動作であっても、Cookieに格納されたSessionIDで検証が合格となってしまうため、処理が実行されてしまうためです。
対策としてSessionID以外のCSRFトークンをhiddenタグで埋め込んでおくなどの対応が必要です。
上記で紹介したCookieのSameSite属性も対策の候補となります。
LocalStorage・SessionStorage・IndexedDBはXSS攻撃を受ける可能性がある
LocalStorage・SessionStorage・IndexedDBはjavascriptによって操作されます。
そのため、悪意あるスクリプトからも操作できてしまいます。
最近利用される機会が増えたJSON Web Token(JWT)も保存しないほうがよいかもしれません。
セキュリティに対してはこちらの内容が一時バズっていました。
[おまけ]LocalStorage・SessionStorage・IndexedDBの使い方
LocalStorageやSessionStorageはjavascriptから容易に使用できるというメリットがあります。
実際の操作方法を紹介するので、その手軽さを感じていただければと思います。
LocalStorage・SessionStorageの操作方法
データの格納
localStorage.setItem('key', 'value');
sessionStorage.setItem('key', 'value');
データの取得
var val = localStorage.getItem('key');
var val = sessionStorage.getItem('key');
データの削除
localStorage.removeItem('key');
sessionStorage.removeItem('key');
いかがでしょうか。非常に楽な操作でデータを保管できることがわかります。
ただし、LocalStorage・SessionStorageには文字列しか格納できないので注意が必要です。
JSONなどを格納する場合は一度文字列に変換して格納する必要があります。
IndexedDBの操作方法
IndexedDBはLocalStorageやSessionStorageと異なりあらかじめ格納先を作成したり使い方に癖があります。
そこで、jdb.jsのようなライブラリを使用するのが良いと思います。jdb.jsの使い方はこちらを参照してください。
IndexedDBは文字列だけでなくJSONをそのまま格納できるというメリットもあります。
これ1冊でゼロから学べる Webプログラミング超入門
【PHP対象】アプリケーションの基礎を体系的に学ぶならこちら。スクールなどもよいですが、費用をかけずにまとまった情報を得るなら隙間時間に技術書をスマホのkindleで読むのがオススメです。