CreaTools LogoCreaTools
Tips

localStorageにトークンを保存するな

2025-12-15

結論:localStorageは「盗まれてもいいデータ」専用

データの種類保存先
ダークモード設定localStorage ✓
認証トークンlocalStorage ✗
フォームの一時保存sessionStorage ✓
パスワードどこにも保存するな

localStorageはJavaScriptから自由に読み書きできる。XSS(クロスサイトスクリプティング)があれば、一発で全部盗まれる。


XSSでlocalStorageが盗まれる流れ

  1. 攻撃者がサイトにスクリプトを埋め込む
  2. ユーザーがそのページを開く
  3. スクリプトがlocalStorage.getItem('token')を実行
  4. 攻撃者のサーバーに送信

localStorageに認証トークンを入れていたら、アカウント乗っ取り完了。


認証トークンはどこに保存する?

方法XSS推奨度
localStorage盗まれる
sessionStorage盗まれる
Cookie(HttpOnly)JSからアクセス不可

**HttpOnly属性を付けたCookieは、JavaScriptから読めない。**XSSがあっても直接は盗めない。


localStorageとsessionStorageの違い

項目localStoragesessionStorage
有効期限永続(削除するまで)タブを閉じるまで
タブ間共有するしない
容量約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
  • プライベートブラウズで使えないことがある