データ保管の仕組みを一挙に解説:
Cache・Session・Cookie・WebStorage・IndexedDBのデータ保管の違い

キャッシュ( Cache )、セッション( Session )、ブラウザに保存される Cookie 、Web Storage( Local StorageSession 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とは用途が大きく異なります。

SessionSessionIDをCookieに保管することにより、SessionIDに紐づいたデータをサーバ上で保管します。

Cookie・Webstorage・IndexedDBはキーバリューデータをブラウザ上で保管するという点が非常に似ています
こちらの違いについては後述にてさらに深堀して説明します。

Recommended You
eyecatch
サンプルソース付:
サイトをアプリ化するPWAとは?作り方と動作イメージを併せて紹介

PWAのメリットや実装方法を紹介しています。興味があればぜひご覧ください。

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・LocalStorageIndexedDBはブラウザやタブを消してもデータが残る一方、SessionStorageはブラウザやタブを消すとデータは消えます
LocalStorageIndexedDBは有効期限がないため、明示的に消さない限りデータは残り続けるということになります。

また、Cookieはサイトを開くごと毎回サーバにデータが送信されるという特徴があります。

クッキーが大量になれば毎回すべてデータが送信されるために重いサイトになってしまいます。

[処理]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によって操作されます。
そのため、悪意あるスクリプトからも操作できてしまいます。

XSS攻撃を受けることを想定し、「LocalStorage・SessionStorage・IndexedDBには重要なユーザー情報を保存しない」という配慮が必要です。

最近利用される機会が増えた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をそのまま格納できるというメリットもあります。

Recommended You
amazon-book-image
HTML,CSS,JavaScript,PHPをまるごとマスター:
これ1冊でゼロから学べる Webプログラミング超入門

【PHP対象】アプリケーションの基礎を体系的に学ぶならこちら。スクールなどもよいですが、費用をかけずにまとまった情報を得るなら隙間時間に技術書をスマホのkindleで読むのがオススメです。

Spread the love