vuejsアプリで認証を行うためにfirebaseを使用しています。私のルート(main.js)のvueコンポーネント。
created() {
auth.onAuthStateChanged((user) => {
this.$store.commit('user/SET_USER', user);
if (user && user.emailVerified) {
this.$store.dispatch('user/UPDATE_VERIFIED', {
userId: user.uid,
});
// SUCCESSFUL LOGIN
this.$router.replace('dashboard');
} else if (user && !user.emailVerified) {
this.$router.replace('verify');
}
});
つまり、基本的に、ルーターのナビゲーションガードは、認証ステータスをチェックし、各ルートの前にもルーティングを実行しています。
router.beforeEach((to, from, next) => {
const currentUser = firebaseApp.auth().currentUser;
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const allowUnverified = to.matched.some(record => record.meta.allowUnverified);
if (requiresAuth && !currentUser) {
next('login');
} else if (currentUser
&& !currentUser.emailVerified
&& !allowUnverified
&& to.path !== '/verify') {
next('verify');
} else if (!requiresAuth && currentUser) {
next('dashboard');
} else {
next();
}
});
(有効な認証トークンを使用して)ページを更新すると、ルートガードのブランチ1であるstateChangesにアクセスし、ハンドラーが呼び出されて/ dashboardにリダイレクトされます。そのため、ログイン中に更新すると、現在のルートではなく、常にダッシュボードルートに移動します。
このケースをどのように処理できますか?各認証コンポーネントにbeforeEnterガードを追加すると、データフェッチVueドキュメントに悪臭がします。
これは、ルートインスタンスで作成されたフックではなく、ストアにある必要がありますか?どんな助けでも大歓迎です。このパターンは私を困惑させています。
ユーザーが存在し、認証を必要としない場合、なぜユーザーを別のページ(ダッシュボード)にリダイレクトするのですか?
} else if (!requiresAuth && currentUser) {
next('dashboard');
} else {
next();
}
ルーティングを続行させることができます。
if (requiresAuth && !currentUser) {
next('login');
} else if (requiresAuth && !currentUser.emailVerified && !allowUnverified) {
next('verify');
} else {
next();
}
またthis.$router.replace('dashboard');
、onAuthStateChanged
コールバックから削除する必要があります。より詳細な回答については、以下を参照してください。
Vueコンポーネントに認証とルーティングロジックを配置することは避けます。いつかは理にかなっているかもしれませんが、この場合は完全に回避できます。
Vuexストアインスタンスを分離されたモジュールに配置して、Vueに限らず他の場所で使用できるようにするのが好きです。
import Vue from 'vue';
import Vuex from 'vuex';
// Configuration is generated with a function, so testing the store is easier
import getConfig from './config';
Vue.use(Vuex);
export default new Vuex.Store(getConfig());
したがって、認証ロジックをauth.js
サービスに移動できます。
import store from './store';
import router from './router';
// other auth related code, you can even export a common API
// to use within your app.
// like this simple wrapper, which hides the fact that you're using firebase
export function getUser() {
return firebaseApp.auth().currentUser;
}
export default { getUser }
auth.onAuthStateChanged((user) => {
// store/business logic should be inside the store.
store.dispatch('user/AUTH_STATE_CHANGED', user);
// minimal handling of mandatory steps in the login or sign up process
if (!user) {
router.push('login');
} else if (user && !user.emailVerified) {
router.push('verify');
}
});
ユーザーが正しくログインしている場合、ここにリダイレクトする理由はありません。グローバルナビゲーションガードがほとんどのリダイレクト作業を実行するため、router.go()
またはを使用して現在のルートにリダイレクトrouter.push(router.currentRoute)
できます。
実際、このナビゲーションガードはauth.js
上記のサービス内に登録することができます。
router.beforeEach((to, from, next) => {
const currentUser = getUser();
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const allowUnverified = to.matched.some(record => record.meta.allowUnverified);
if (requiresAuth && !currentUser) {
next('login');
} else if (requiresAuth && !currentUser.emailVerified && !allowUnverified) {
next('verify');
} else {
next();
}
});
次に、ログインすると到達できないルートに簡単なナビゲーションガードを追加します。
path: '/login',
beforeEnter: (to, from, next) => {
if (auth.getUser()) {
next('dashboard');
} else {
next();
}
},
重要なのは、制限されたページに移動するときにのみリダイレクトを強制することです。
ログインしたユーザーがページを更新するときに、にリダイレクトする理由はありません/dashboard
。同じユーザーがログインに移動しようとする場合は、にリダイレクトする理由があります/dashboard
。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加