まず結論
ブラウザには、サイトごとにデータを保存する場所がいくつかあります。代表的なのが localStorage、sessionStorage、Cookie、そして JavaScript の変数です。
この4つは、どれも「ブラウザ側にあるデータ」に見えます。しかし性質はまったく違います。
| 保存場所 | JavaScriptから読めるか | サーバへ自動送信されるか | リロードで消えるか | 主な用途 |
|---|---|---|---|---|
| JavaScript変数 | 読める | 送られない | 消える | 一時的な画面状態 |
| sessionStorage | 読める | 送られない | 消えない | タブ内だけの一時保存 |
| localStorage | 読める | 送られない | 消えない | 設定値などの永続保存 |
| Cookie | 条件次第 | 自動送信される | 設定次第 | セッション管理、ユーザー識別 |
ポイント: 認証情報を置く場所として特に注意が必要なのは、JavaScriptから読める保存場所です。XSSが起きると、攻撃者のJavaScriptにも読まれる可能性があります。
localStorage とは
localStorage は、ブラウザが提供するキー・バリュー形式の保存場所です。JavaScriptから簡単に読み書きできます。
localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme");
console.log(theme); // "dark"
保存したデータは、同じオリジンのページから読めます。ここでいうオリジンとは、https://example.com のような「スキーム、ホスト、ポート」の組み合わせです。
localStorage の特徴は、ブラウザを閉じても基本的に残ることです。普通のリロード、スーパーリロード、タブを閉じる操作では消えません。
| 操作 | localStorage は消えるか |
|---|---|
| 普通のリロード | 消えない |
| スーパーリロード | 消えない |
| タブを閉じる | 消えない |
| ブラウザを終了する | 消えない |
| サイトデータを削除する | 消える |
JavaScriptで removeItem() する | 消える |
sessionStorage とは
sessionStorage は、タブ単位で保存されるデータ置き場です。
sessionStorage.setItem("draft", "入力途中のメモ");
const draft = sessionStorage.getItem("draft");
localStorage と同じくJavaScriptから読めますが、保存期間が違います。タブを閉じると、そのタブの sessionStorage は消えます。
| 操作 | sessionStorage は消えるか |
|---|---|
| 普通のリロード | 消えない |
| スーパーリロード | 消えない |
| 同じタブでページ遷移 | 消えない |
| タブを閉じる | 消える |
| ブラウザを終了する | 多くの場合消える |
ログイン後の高価値なトークンを置く場所としては、localStorage より短命にできます。ただし、JavaScriptから読める点は変わりません。
Cookie とは
Cookie は、サーバがブラウザに保存を依頼する小さなデータです。
ログイン成功時、サーバはレスポンスに Set-Cookie ヘッダーを付けます。
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
するとブラウザは、そのCookieを保存します。次回以降、条件に合うリクエストではブラウザが自動でCookieを付けます。
GET /mypage HTTP/1.1
Host: example.com
Cookie: session_id=abc123
ここが localStorage との大きな違いです。localStorage はJavaScriptが取り出して送る必要がありますが、CookieはブラウザがHTTP通信に自動で付けます。
JavaScript変数は一番短命
JavaScriptの変数は、ページが読み込まれている間だけ存在します。
let accessToken = "xxxxx.yyyyy.zzzzz";
普通のリロードをすると、JavaScriptは最初から実行し直されます。そのため、変数の中身は消えます。
この性質を利用して、SPAではアクセストークンをメモリ上だけに持つ設計があります。localStorage に永続保存しないため、盗まれたときの被害を小さくできます。ただし、リロード後にログイン状態をどう復元するかという別の課題が出ます。
認証情報を置くときの考え方
認証情報には、次のようなものがあります。
- セッションID
- アクセストークン
- リフレッシュトークン
- JWT
これらは「持っている人を本人として扱う」材料になることがあります。したがって、保存場所の選択はセキュリティに直結します。
| 置くもの | localStorage | Cookie | メモリ |
|---|---|---|---|
| 画面テーマ | 向いている | 不要なことが多い | 消えてよいなら可 |
| 入力途中の下書き | 場合による | 不向き | 短命なら可 |
| セッションID | 不向き | HttpOnly Cookie が定番 | 不向き |
| access token | XSSに弱い | HttpOnly Cookie またはサーバ側管理 | 短命なら候補 |
| refresh token | かなり危険 | 要件次第でHttpOnly Cookie、より安全にはサーバ側 | 不向き |
注意: localStorage が悪いわけではありません。危険なのは、漏れたら本人になりすませるトークンを、JavaScriptから読める場所に長く置くことです。
スーパーリロードでは何が消えるのか
スーパーリロードは、主にブラウザのキャッシュを無視してHTML、CSS、JavaScript、画像などを再取得する操作です。
localStorage や Cookie を削除する操作ではありません。
| データ | スーパーリロードで消えるか |
|---|---|
| HTTPキャッシュ | 再取得される |
| JavaScript変数 | ページ再読み込みで消える |
| sessionStorage | 基本的に残る |
| localStorage | 残る |
| Cookie | 残る |
CookieやlocalStorageを消したい場合は、ブラウザのサイトデータ削除、開発者ツール、またはアプリ側のログアウト処理で削除します。
まとめ
localStorage は、JavaScriptから読めて、リロードやブラウザ終了後も残る保存場所です。設定値や軽い状態保存には便利ですが、認証トークンを置くとXSS時に盗まれやすくなります。
Cookie は、ブラウザがサーバへ自動送信する保存場所です。HttpOnly を付けるとJavaScriptから読めなくなるため、セッションIDの保存に向いています。
認証設計では、次の一文をまず覚えてください。
実践メモ: ブラウザに長く残る場所ほど便利ですが、漏れたときの被害も大きくなります。保存期間と読み取り権限を分けて考えることが重要です。
参考リソース
- 公式ドキュメント - localStorage と Cookie の違い - ブラウザに残るデータの基本 を確認するための一次情報
次に読む記事
- Cookie はなぜ自動で送られるのか
- JWT を localStorage に置くなと言われる理由
- Cookie の仕組み - Set-Cookie / SameSite / Secure / HttpOnly