Tips
localStorageにトークンを保存するな
2025-12-15
結論:localStorageは「盗まれてもいいデータ」専用
| データの種類 | 保存先 |
|---|---|
| ダークモード設定 | localStorage ✓ |
| 認証トークン | localStorage ✗ |
| フォームの一時保存 | sessionStorage ✓ |
| パスワード | どこにも保存するな |
localStorageはJavaScriptから自由に読み書きできる。XSS(クロスサイトスクリプティング)があれば、一発で全部盗まれる。
XSSでlocalStorageが盗まれる流れ
- 攻撃者がサイトにスクリプトを埋め込む
- ユーザーがそのページを開く
- スクリプトが
localStorage.getItem('token')を実行 - 攻撃者のサーバーに送信
localStorageに認証トークンを入れていたら、アカウント乗っ取り完了。
認証トークンはどこに保存する?
| 方法 | XSS | 推奨度 |
|---|---|---|
| localStorage | 盗まれる | ✗ |
| sessionStorage | 盗まれる | ✗ |
| Cookie(HttpOnly) | JSからアクセス不可 | ✓ |
**HttpOnly属性を付けたCookieは、JavaScriptから読めない。**XSSがあっても直接は盗めない。
localStorageとsessionStorageの違い
| 項目 | localStorage | sessionStorage |
|---|---|---|
| 有効期限 | 永続(削除するまで) | タブを閉じるまで |
| タブ間共有 | する | しない |
| 容量 | 約5MB | 約5MB |
ブラウザを閉じても残すならlocalStorage、タブ限定ならsessionStorage。
基本的な使い方
// 保存
localStorage.setItem('theme', 'dark');
// 取得
const theme = localStorage.getItem('theme');
// 削除
localStorage.removeItem('theme');
// 全削除
localStorage.clear();
オブジェクトはJSONにして保存。
// 保存
localStorage.setItem('user', JSON.stringify({ name: '田中' }));
// 取得
const user = JSON.parse(localStorage.getItem('user'));
私がやらかした失敗
「JWTトークンをlocalStorageに保存すれば楽」
→ セキュリティレビューで指摘 → 「XSSがあったら全ユーザーのトークンが盗まれる」 → HttpOnly Cookieに変更
楽だからといって、認証情報をlocalStorageに入れてはいけない。
実装例:フォームの一時保存
const form = document.getElementById('form');
// 入力中に保存
form.addEventListener('input', () => {
const data = {
name: form.name.value,
email: form.email.value,
};
sessionStorage.setItem('draft', JSON.stringify(data));
});
// ページ読み込み時に復元
window.addEventListener('load', () => {
const draft = sessionStorage.getItem('draft');
if (draft) {
const data = JSON.parse(draft);
form.name.value = data.name || '';
form.email.value = data.email || '';
}
});
// 送信成功時に削除
form.addEventListener('submit', () => {
sessionStorage.removeItem('draft');
});
途中でブラウザを閉じても、再入力の手間が省ける。
プライベートブラウズの注意
Safariのプライベートブラウズでは、localStorageが使えないことがある。
function isStorageAvailable() {
try {
localStorage.setItem('test', 'test');
localStorage.removeItem('test');
return true;
} catch (e) {
return false;
}
}
使えない場合のフォールバックを用意する。
まとめ
- localStorageは「盗まれてもいいデータ」専用
- 認証トークンはHttpOnly Cookie
- ブラウザを閉じても残すならlocalStorage
- タブ限定ならsessionStorage
- プライベートブラウズで使えないことがある