ha6_6ruブログ

主にフロントエンドの技術ネタを中心にしていく予定です。

Vue 3 Auth Guard(未認証の場合にログインページにリダイレクト)

はじめに

次のような振る舞いを実現する場合、Vue.js(Vue Router)ではナビゲーションガードを利用します。

  • ECサイトで購入手続きに入ろうとしたときにログインページに飛ばされる
  • 最初にログインが必要なサイトで、ログイン以降に表示されるページにアクセスしたときにログインページに飛ばされる

ナビゲーションガード

ナビゲーションガードには、グローバルやルートごとの設定、コンポーネント内の設定と種類が分かれますが、サイト全体の認証を制御するのでグローバルナビゲーションガードを使います。グローバルナビゲーションガードは、Vue Routerのインスタンスに対して設定を行います。
まずは、未認証のときにログインページにリダイレクトするナビゲーションガードの実装を紹介します。

ナビゲーションガードの実装サンプル

  • auth-guard.ts
import type { Router } from 'vue-router';
import { useAuthenticationStore } from '@/stores/authentication';
import { useRoutingStore } from '@/stores/routing';

export const authenticationGuard = (router: Router) => {
  const authenticationStore = useAuthenticationStore();
  const routingStore = useRoutingStore();

  router.beforeEach((to) => {
    // 既に認証されていれば何もしない
    if (authenticationStore.isAuthenticated) {
      return true;
    }

    // 未認証状態で遷移を許可するルート
    if (['login', 'home'].includes(to.name)) {
      return true;
    }

    // 認証後のリダイレクトで使う。必要に応じてパラメーターも保存しておく。
    routingStore.setRedirectFrom(to.name);

    return { name: 'login' };
  });
};

認証状態はストアで扱うことを前提とした実装になっています。メモリやストレージなど、実際の保存先はストア内で決定します。
遷移しようとしたページに移動させずにログインページにリダイレクトしたいので、beforeEachを使います。beforeEachはVue Routerによるナビゲーションが確定する前のフックです。
ログイン後に元々アクセスしようとしていたページに移動して手続きを続行したいので、アクセスしようとしていたページの情報と必要に応じて遷移時のパラメーターを保存しておき、ログイン後にそれらの情報を使ってアクセスしようとしていたページに遷移します。ECサイトの例では、ログイン後には購入手続きに自動的に遷移します。
この実装サンプルでは次のような条件判定を行っています。

  • 認証されていれば何もせずに遷移しようとしたページに移動
  • 未認証状態で表示してもよいページに対しては何もせず、遷移しようとしたページに移動
  • 上記以外はログインページにリダイレクト

グローバルナビゲーションガードの登録

先ほど作った関数にcreateRouterで生成したVue Routerのインスタンスを渡すことで、グローバルナビゲーションガードとして動作します。

authenticationGuard(router);