認証情報って、結局どこに入れるのがいいの？



## この記事で達成できること
### 対象者
- 認証情報をどこにいれればいいかわからない人
- `localStorage`や`sessionStrage`、`cookie`の違いや詳細を知らない人

### 達成できること
- 認証情報をどこに入れれば良いかわかる
- それぞれの格納先に、どのタイプの情報を入れるのが適しているかがわかる


## 先に結論
#### 簡単に実装するなら、sessionStorage
#### ちゃんと実装するなら、cookie

というのが個人的な結論かな？

ただ、いろんな記事を読んでいく中で、セキュリティちゃんとしたいならサーバーサイド用意しなきゃだよねって結論になった。
自分のやろうとしているFirebase×Reactは、PoC程度しか使えないかなぁ...

https://qiita.com/NewGyu/items/0b3111b61405366a76c5

## localStorage
### ◎活用シーン
<dl>
  <dt>Googleマップ</dt>
  <dd>フォームの入力途中の状態やショッピングカートの中身などを保存している。</dd>
  <dt>Twitter</dt>
  <dd>
  ユーザのインターフェース設定（ダークモードやライトモードの設定）をlocalStorageに保存している。
  これにより、ユーザが再訪した時に、前回選んだ設定が維持される。
  </dd>
</dl>

### ◎データの生存期間
手動で削除されるまで、永続的に保持される。

<dl>
  <dt>（削除例）</dt>
  <dd>
      ① アプリ側で何かしらのトリガーで削除されるようにした場合
  </dd>
  <dd>
      ② ユーザがブラウザのキャッシュを削除したり、devtoolなどで削除した場合
  </dd>
</dl>

### ◎データ容量
5〜10MBのデータを保持可能。

### ◎データのアクセス可能領域
クライアントサイド（javascript）からのみアクセス可能。

### ◎データの保存形式
文字列形式（string）

### ◎セキュリティリスク
<dl>
  <dt>XSS攻撃（クロスサイトスプリクティング）</dt>
  <dd>
      localStorageはJacascriptからアクセス可能なため、XSS攻撃によって悪意のあるスクリプトが実行されると、データが盗まれる可能性がある
  </dd>
</dl>
  

### ◎脆弱性の対策
<dl>
  <dt>入力の検証とサニタイズ</dt>
  <dd>
      ユーザの入力を保存する前に、必ず入力を検証し、サニタイズすることで、XSS攻撃のリスクを軽減する

  </dd>
</dl>
</dl>

### ◎ReactやReduxで使いたい時は？
#### Typescriptによる基本的な操作
```typescript:データの保存
localStorage.setItem('key', 'value');
```
```typescript:データの取得
const value = localStorage.getItem('key');
```
```typescript:データの削除
localStorage.removeItem('key');
```
```typescript:全データのクリア
localStorage.clear();
```

#### redux-persist
```bash:ライブラリのインストール
npm install redux-persist
```

```typescript:設定の作成
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);
```

```typescript:ストアの設定
import { configureStore } from '@reduxjs/toolkit';
import { persistStore } from 'redux-persist';

const store = configureStore({
  reducer: persistedReducer,
});

const persistor = persistStore(store);
```

```typescript: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')
);
```

https://qiita.com/yasuhiro-yamada/items/bd86d7c9f35ebb1c1e7c

#### ◎その他：useSyncExternalStore: 
Reactの新しいフックで、localStorageの変更を検知してコンポーネントを再レンダリングさせることができる

https://zenn.dev/daiki_21/articles/6b63cd3201bd7d

## sessionStorage
### ◎活用シーン
<dl>
  <dt>
      Googleマップ
  </dt>
  <dd>
      各タブごとに独立したセッションデータを持たせ、異なるタブで異なる場所を検索してもデータが混在しない
  </dd>
    <dt>
      フォーム入力の保持
  </dt>
  <dd>
      ユーザがページを離れても、同じタブ内で戻った際に入力内容を保持するために利用されることがある
  </dd>
</dl>

### ◎データの生存期間
- ブラウザセッション中のみ生存する
- ブラウザを閉じるとデータは削除される
- リロード時は保持される

### ◎データ容量
5〜10MBのデータを保持可能。

### ◎データのアクセス可能領域
- クライアントサイド（JavaScript）からのみアクセス可能
- 他のタブやウィンドウからはアクセスできない

### ◎データの保存形式
- 文字列形式
- キーとバリューのペアのセットで扱われる

### ◎セキュリティリスク
<dl>
  <dt>
      XSS攻撃
  </dt>
  <dd>
      （省略）
  </dd>
    <dt>
      CSRF攻撃（クロスサイトリクエストフォージェリ）
  </dt>
  <dd>
      セッションハイジャックのリスクがある
  </dd>
</dl>

### ◎脆弱性の対策
<dl>
  <dt>
      CSP（Content Security Policy）
  </dt>
  <dd>
      ブラウザに対して、どのリソースを許可するかを指定する
      
  </dd>
</dl>

### ◎ReactやReduxでの使用方法
#### Typescriptによる基本的な操作
```typescript:データの保存
sessionStorage.setItem('key', 'value');
```
```typescript:データの取得
const value = sessionStorage.getItem('key');
```
```typescript:データの削除
sessionStorage.removeItem('key');
```
```typescript:全データのクリア
sessionStorage.clear();
```
#### redux-persist
上述したのと同じ方法

## Cookie

### ◎活用シーン
<dl>
  <dt>
      Amazon
  </dt>
  <dd>
      ログイン状態やショッピングカートの内容を保存するためにCookieを使用している
  </dd>
  <dd>
      ユーザがページを移動、ブラウザを閉じて後でサイド開いた時でも自分が選んだ商品がショッピングカートに残っている
  </dd>
</dl>

### ◎データの生存期間
<dl>
  <dt>
      セッションCookie
  </dt>
  <dd>
      ブラウザを閉じると削除される
  </dd>
  <dt>
      永続Cookie
  </dt>
  <dd>
      特定の有効期限まで保存される。数日から数年まで設定可能。
  </dd>
</dl>
### ◎データ容量
4KB

### ◎データのアクセス可能領域
- サーバーとクライアントサイドからアクセス可能
- 他のタブやウィンドウからはアクセスできない

### ◎データの保存形式
- 文字列形式
- キーとバリューのペアのセットで扱われる

### ◎セキュリティリスク
<dl>
  <dt>
      XSS攻撃
  </dt>
  <dd>
      （省略）
  </dd>
    <dt>
      CSRF攻撃（クロスサイトリクエストフォージェリ）
  </dt>
  <dd>
      セッションハイジャックのリスクがある
  </dd>
</dl>

### ◎脆弱性の対策
<dl>
  <dt>
      セキュア属性の設定
  </dt>
  <dd>
      CookieをHTTPS通信でのみ送信するように設定する
  </dd>
  <dt>
      HttpOnly属性の設定
  </dt>
  <dd>
      JavaScriptからアクセスできないようにすることで、XSS（クロスサイトスクリプティング）攻撃から保護します。
  </dd>
  <dt>
      SameSite属性の設定
  </dt>
  <dd>
      クロスサイトリクエストフォージェリ（CSRF）攻撃を防ぐために、SameSite属性を設定します。
  </dd>
  
  <dt>
      有効期限の設定
  </dt>
  <dd>
      適切な有効期限を設定し、不要なCookieは早めに削除します。

  </dd>
</dl>

### ◎ReactやReduxでの使用方法
#### react-cookie
```bash:インストール
npm install react-cookie
```

https://zenn.dev/iroristudio/articles/0bc4729fefbc41

## この記事を書くにあたり、大いに参考にさせていただきました

https://zenn.dev/tm35/articles/584ece2d771a4b