web-dev-qa-db-ja.com

Redux / Redux-Sagaを使用する場合-JWTをアクションクリエーター/サガに設定する必要がありますか?

React/Redux/SagaアプリケーションでJWTを使用した一般的な認証処理に関して私が遭遇したほぼすべてのブログ投稿は、アクション/サガでローカルストレージのJWTを格納することと同じことを行います。

例えば:

例A(redux-saga)

function* authorize({ payload: { login, password } }) {
  const options = {
    body: JSON.stringify({ login, password }),
    method: 'POST',
    headers: { 'Content-Type': 'application/json' }
  };

  try {
    const { token } = yield call(fetchJSON, '/login', options);
    yield put({ type: AUTH_SUCCESS, payload: token });
    localStorage.setItem('token', token);
  } catch (error) {
    let message;
    switch (error.status) {
      case 500: message = 'Internal Server Error'; break;
      case 401: message = 'Invalid credentials'; break;
      default: message = 'Something went wrong';
    }
    yield put({ type: AUTH_FAILURE, payload: message });
    localStorage.removeItem('token');
  }
}

function* Saga() {
  yield takeLatest(AUTH_REQUEST, authorize);
}

例B(redux):

function login(username, password) {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ username, password })
    };

    return fetch(`${config.apiUrl}/users/authenticate`, requestOptions)
        .then(handleResponse)
        .then(user => {
            // login successful if there's a jwt token in the response
            if (user.token) {
                // store user details and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('user', JSON.stringify(user));
            }

            return user;
        });
}

function logout() {
    // remove user from local storage to log user out
    localStorage.removeItem('user');
}

今-ローカルストレージにJWTを保存する-何が問題なのか-レデューサーではなく、アクションクリエーター/サガ内の状態の設定です

私の理解では、アクションクリエーター/サガは、使用するデータを決定するためにのみ使用する必要があり、データを実際に保存/保持するのはレデューサー次第です

もちろん-初期状態では、reduxはデータを保持しません。ただし、redux-persistなどのreduxミドルウェアを使用してローカルストレージに永続化することができます(他の場所にデータを永続化する他のredux-persistミドルウェアもあります)。ここでのポイントは-reduxは状態管理です

それでは、なぜ-認証に関しては、アプリケーションの状態としてreduxを使用することを避けているのでしょうか?

1
dwjohnston

さまざまなソースから推測します。

  1. 「セキュリティは横断的関心事ではない」と聞いたので、認証を入れました。モデルには含まれていませんが、プログラムから切り離して、必要に応じて押し込むことはできません。
  2. 認証されているかどうかは、2つのオブジェクト(1つは認証済み、もう1つは同時に認証されていない)を持っているという点では、モデルの一部ではありません。

したがって、他のロジックから遠く離れたところに認証をプッシュしようとします。コミュニケーションとモデルの間の層にそれを置きます。このレイヤーは非常に薄いため、このレイヤーは例に基づいて構築されたプログラムで予期しない方法で進化したり進化したりしない可能性があるため、例では追加のスペースを与えません。その上、そのユースケースを処理する場所は2つしかありません。

もう1つは、例では、完璧ではなく単純さを追求することです。

PS:このような答えは通常、より良い答えを導きます。幸運を!

2
User

私にとって、トークンをreduxストアではなくローカルストレージに保存する主な理由は、トークンが本質的に本質的に異なるためです。

  • 通常、ページを更新する間も認証トークンを保持したい
  • あなたはアプリケーションの状態でそれをしたいかどうか

それとは別に、アクションの作成者に状態を設定することは私には間違っているようです。なぜなら、それらの唯一の責任はアクションを返すことであるべきだからです。

ローカルストレージの設定は当然のことながら副作用であるため、論理的な場所は、選択した副作用ハンドラー(多くの場合、saga)内にあるようです。

2
Tiago Coelho