web-dev-qa-db-ja.com

ルートに入る前に有効な認証トークンを確認するVue router

私のアプリケーションがvue-routerおよびvuex。次に、storeには、userで始まるnullオブジェクトが含まれます。ユーザーはサーバーから検証された後、ストア内のuserオブジェクトに割り当てられたJWT認証トークンを含むuserオブジェクトを送り返します。ここで、ユーザーが3時間後に戻ってきて、ルートにアクセスしたり、他のアクションを実行しようとした場合、認証トークンの有効期限が切れていることを考慮して、それを確認する最良の方法は何でしょうか(axios postをチェックして)ユーザーをloginページにリダイレクトします。アプリには多数のコンポーネントがあるため、各コンポーネントのmountedフックで有効なトークンをチェックするロジックを作成できることはわかっていますが、それはすべてのコンポーネントを繰り返すことを意味します。また、beforeEachナビゲーションガードを使用したくありません。checking...またはloading...

11
Soham Dasgupta

Vue.JSをお試しください Mixins

グローバルミックスインを定義し、Vue.use(myMixin)経由で使用できます。すべてのコンポーネントがこのミックスインを継承します。ミックスインでmountedフックまたはおそらくactivatedフックを定義すると、すべてのコンポーネントで呼び出されます。

そこで、コンポーネントができることはすべて使用できます-thisはコンポーネントを指します。また、コンポーネントがフック自体も定義している場合、同じタイプのミックスインフックは、コンポーネントが所有するフックの前に実行されます。

または、単一のトップレベルログインコンポーネントを試してください

少し異なるソリューションを使用しました。親index.htmlのルータービューの外部に存在する、ログイン関連のすべてを処理する単一のコンポーネントがあります。このコンポーネントは常にアクティブであり、div router-viewを非表示にして、読み込みメッセージまたはログイン画面をオーバーレイできます。イントラネットアプリケーションの場合、このコンポーネントはポーリングを使用して、ブラウザが開いている限りセッションを維持します。

このコンポーネントにルーターナビゲーションを読み込むことができます。 -そのため、ルーターナビゲーションをトリガーする子コンポーネントは、トップレベルの認証コンポーネントによって監視されるグローバルなリアクティブプロパティnavigateToを設定するだけです。これにより、認証チェック、場合によってはログインワークフローがトリガーされ、その後、トップレベルコンポーネントが$router.Push()を呼び出します。このアプローチでは、ナビゲーションを完全に制御できます。

9
Falco

私は私のプロジェクトの1つで同様のことをします。実際にこれらのタイプの状況を処理するのは一見難しいですが、保護されたルートにbeforeEnterガードを追加し、認証が失敗した場合にリダイレクトすることができます。

const guard = function(to, from, next) {
  // check for valid auth token
  axios.get('/api/checkAuthToken').then(response => {
      // Token is valid, so continue
      next();
  }).catch(error => {
      // There was an error so redirect
      window.location.href = "/login";
  })
};

その後、あなたのルートで次のことができます:

{
  path: '/dashboard',
  component: Dashboard,
  beforeEnter: (to, from, next) => {
    guard(to, from, next);
  }
},

あなたは私がlocation.href のではなく router.Push。ログインフォームがcsrfで保護されているため、新しいcsrf_tokenが必要です。

他の問題は、ユーザーがルートを変更せずにページを操作しようとした場合(つまり、ボタンをクリックして401応答を取得した場合)です。このため、各axiosリクエストで認証を確認し、401応答を受け取ったときにloginにリダイレクトするのが最も簡単です。

ガードチェック中にロードスピナーを追加するという点では、vuexストアにロードフラグを追加してから、ストアをルーターにインポートするだけです。正直なところ、私は気にしませんが、まともな実稼働サーバーでは、チェックが非常に迅速に行われるため、ユーザーはそれを見ることがほとんどありません。

9
craig_h

vuexを使用するため、isLoadingisCheckingなどの状態を追加できます。

そしてあなたのrouter.beforeEach、現在のチェック状態に従ってisLoadingまたはisCheckingを確認および設定できます。次に、この状態に従って読み込みメッセージを表示できます。

4
Anh Nguyen

interceptorsを使用して、何らかのリクエストが発生したときに認証トークンをサイレントに取得できます。

    axios.interceptors.response.use(function (response) {
         return response;
       }, function (error) {

              const originalRequest = error.config;

             if (error.response.status === 401 && !originalRequest._retry) {

              originalRequest._retry = true;

              const rToken = window.localStorage.getItem('rToken');
              return axios.post('url/to/get/refresh/token', { rToken })
                     .then(({data}) => {
                     window.localStorage.setItem('token', data.token);
                     window.localStorage.setItem('rToken', data.refreshToken);
                     axios.defaults.headers.common['Authorization'] = 'Bearer ' + data.token;
                    originalRequest.headers['Authorization'] = 'Bearer ' + data.token;
                    return axios(originalRequest);
           });
      }

      return Promise.reject(error);
   });
4
Thaadikkaaran