この記事で達成できること
対象者
- 認証情報をどこにいれればいいかわからない人
-
localStorage
やsessionStrage
、cookie
の違いや詳細を知らない人
達成できること
- 認証情報をどこに入れれば良いかわかる
- それぞれの格納先に、どのタイプの情報を入れるのが適しているかがわかる
先に結論
簡単に実装するなら、sessionStorage
ちゃんと実装するなら、cookie
というのが個人的な結論かな?
ただ、いろんな記事を読んでいく中で、セキュリティちゃんとしたいならサーバーサイド用意しなきゃだよねって結論になった。
自分のやろうとしているFirebase×Reactは、PoC程度しか使えないかなぁ...
localStorage
◎活用シーン
- Googleマップ
- フォームの入力途中の状態やショッピングカートの中身などを保存している。
- ユーザのインターフェース設定(ダークモードやライトモードの設定)をlocalStorageに保存している。 これにより、ユーザが再訪した時に、前回選んだ設定が維持される。
◎データの生存期間
手動で削除されるまで、永続的に保持される。
- (削除例)
- ① アプリ側で何かしらのトリガーで削除されるようにした場合
- ② ユーザがブラウザのキャッシュを削除したり、devtoolなどで削除した場合
◎データ容量
5〜10MBのデータを保持可能。
◎データのアクセス可能領域
クライアントサイド(javascript)からのみアクセス可能。
◎データの保存形式
文字列形式(string)
◎セキュリティリスク
- XSS攻撃(クロスサイトスプリクティング)
- localStorageはJacascriptからアクセス可能なため、XSS攻撃によって悪意のあるスクリプトが実行されると、データが盗まれる可能性がある
◎脆弱性の対策
- 入力の検証とサニタイズ
- ユーザの入力を保存する前に、必ず入力を検証し、サニタイズすることで、XSS攻撃のリスクを軽減する
◎ReactやReduxで使いたい時は?
Typescriptによる基本的な操作
データの保存
localStorage.setItem('key', 'value');
データの取得
const value = localStorage.getItem('key');
データの削除
localStorage.removeItem('key');
全データのクリア
localStorage.clear();
redux-persist
ライブラリのインストール
npm install redux-persist
設定の作成
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
ストアの設定
import { configureStore } from '@reduxjs/toolkit';
import { persistStore } from 'redux-persist';
const store = configureStore({
reducer: persistedReducer,
});
const persistor = persistStore(store);
Reactアプリに統合
import { PersistGate } from 'redux-persist/integration/react';
import { Provider } from 'react-redux';
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById('root')
);
◎その他:useSyncExternalStore:
Reactの新しいフックで、localStorageの変更を検知してコンポーネントを再レンダリングさせることができる
sessionStorage
◎活用シーン
- Googleマップ
- 各タブごとに独立したセッションデータを持たせ、異なるタブで異なる場所を検索してもデータが混在しない
- フォーム入力の保持
- ユーザがページを離れても、同じタブ内で戻った際に入力内容を保持するために利用されることがある
◎データの生存期間
- ブラウザセッション中のみ生存する
- ブラウザを閉じるとデータは削除される
- リロード時は保持される
◎データ容量
5〜10MBのデータを保持可能。
◎データのアクセス可能領域
- クライアントサイド(JavaScript)からのみアクセス可能
- 他のタブやウィンドウからはアクセスできない
◎データの保存形式
- 文字列形式
- キーとバリューのペアのセットで扱われる
◎セキュリティリスク
- XSS攻撃
- (省略)
- CSRF攻撃(クロスサイトリクエストフォージェリ)
- セッションハイジャックのリスクがある
◎脆弱性の対策
- CSP(Content Security Policy)
- ブラウザに対して、どのリソースを許可するかを指定する
◎ReactやReduxでの使用方法
Typescriptによる基本的な操作
データの保存
sessionStorage.setItem('key', 'value');
データの取得
const value = sessionStorage.getItem('key');
データの削除
sessionStorage.removeItem('key');
全データのクリア
sessionStorage.clear();
redux-persist
上述したのと同じ方法
Cookie
◎活用シーン
- Amazon
- ログイン状態やショッピングカートの内容を保存するためにCookieを使用している
- ユーザがページを移動、ブラウザを閉じて後でサイド開いた時でも自分が選んだ商品がショッピングカートに残っている
◎データの生存期間
- セッションCookie
- ブラウザを閉じると削除される
- 永続Cookie
- 特定の有効期限まで保存される。数日から数年まで設定可能。
◎データのアクセス可能領域
- サーバーとクライアントサイドからアクセス可能
- 他のタブやウィンドウからはアクセスできない
◎データの保存形式
- 文字列形式
- キーとバリューのペアのセットで扱われる
◎セキュリティリスク
- XSS攻撃
- (省略)
- CSRF攻撃(クロスサイトリクエストフォージェリ)
- セッションハイジャックのリスクがある
◎脆弱性の対策
- セキュア属性の設定
- CookieをHTTPS通信でのみ送信するように設定する
- HttpOnly属性の設定
- JavaScriptからアクセスできないようにすることで、XSS(クロスサイトスクリプティング)攻撃から保護します。
- SameSite属性の設定
- クロスサイトリクエストフォージェリ(CSRF)攻撃を防ぐために、SameSite属性を設定します。
- 有効期限の設定
- 適切な有効期限を設定し、不要なCookieは早めに削除します。
◎ReactやReduxでの使用方法
react-cookie
インストール
npm install react-cookie
この記事を書くにあたり、大いに参考にさせていただきました