我有一个带有i18n的Vue SPA和一些需要通过导航守卫进行身份验证的视图。
当我没有通过身份验证并通过浏览器访问url时:
examplepage.com/en/lockedpage
我被重定向到:
examplepage.com/en/login
这很好,但是当我点击一个按钮运行:
@click="$router.push(`/${$i18n.locale}/lockedpage`)"
即使我没有经过身份验证,我也可以进入页面。我想重定向到登录页面,如果没有验证
这是我的router.js:
import Vue from 'vue';
import Router from 'vue-router';
import Home2 from './views/Home2.vue';
import Login from './views/Login.vue';
import Register from './views/Register.vue';
import ErrorLanding from './views/ErrorLanding.vue'
import Root from "./Root"
import i18n, { loadLocaleMessagesAsync } from "@/i18n"
import {
setDocumentLang
} from "@/util/i18n/document"
Vue.use(Router);
const { locale } = i18n
export const router = new Router({
mode: 'history',
base: '/',
routes: [
{
path: '/',
redirect: locale
},
{
path: "/:locale",
component: Root,
children: [
{
name: 'Home',
path: '',
component: Home2,
},
{
name: 'Home2',
path: '/',
component: Home2,
},
{
name: 'Login',
path: 'login',
component: Login,
},
{
path: 'register',
component: Register,
},
{
path: 'lockedpage',
name: 'lockedpage',
webpackChunkName: "lockedpage",
meta: {authRequired: true},
component: () => import('./views/LockedPage.vue')
},
{
path: '*',
component: ErrorLanding,
name: 'NotFound'
}
]
}
],
router.beforeEach((to, from, next) => {
if (to.params.locale === from.params.locale) {
next()
return
}
const { locale } = to.params
loadLocaleMessagesAsync(locale).then(() => {
setDocumentLang(locale)
const publicPages = [ `/`, `/${locale}`, `/${locale}/`];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
const redirect = to.path;
if (authRequired && loggedIn === null) {
if(to.meta.authRequired === false) {
next();
}
else
next({ name: 'Login', query: { redirect: redirect } });
} else {
next();
}
})
next()
});
为什么我的navigationguard跳过当使用router.push() ?这个问题是在使用localeredirect添加i18n后开始的。所以所有的路由都在区域设置之后,例如:/en/…/
正如Estus在评论中指出的那样,问题是您要检查的第一件事是区域设置是否匹配,如果匹配,则调用next()
并将用户发送到页面。
如下所示:
确保在通过导航保护的任何给定传递中只调用next函数一次。它可以出现多次,但前提是逻辑路径没有重叠,否则钩子将永远不会被解析或产生错误。
如果需要在to和from页面之间保持区域设置检查,可以这样做:
if (to.params.locale === from.params.locale && loggedIn) {
next()
return
}
,它将在将用户推送到他们试图导航到的页面之前检查loggedIn变量是否为真。
我相信只要去掉if语句来检查区域设置是否匹配就可以了。