Vue.js:如何保护登录组件免受经过身份验证的用户的影响
Posted
技术标签:
【中文标题】Vue.js:如何保护登录组件免受经过身份验证的用户的影响【英文标题】:Vue.js: How to protect login component from authenticated user 【发布时间】:2020-05-22 16:24:01 【问题描述】:我正在设计一个使用 firebase-auth 实现身份验证的应用程序。我已经保护了用户组件免受未经身份验证的用户的影响。但我现在想保护登录组件免受经过身份验证的用户的影响。到目前为止,我已经尝试过了。这是我的路由器/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import
fb
from "@/firebase/init";
import Home from '@/views/Home'
Vue.use(VueRouter)
const routes = [
path: '/',
name: "home",
component: Home
,
path: '/login',
name: 'login',
component: () => import('@/components/auth/Login'),
meta:
alreadyAuth: true
,
path: '/signup',
name: 'signup',
component: () => import('@/components/auth/Signup'),
,
path: '/user/:id',
name: 'user',
component: () => import('@/components/user/User'),
meta:
requiresAuth: true
,
]
const router = new VueRouter(
mode: 'history',
base: process.env.BASE_URL,
routes
)
router.beforeEach((to, from, next) =>
let user = fb.auth().currentUser
if (to.matched.some(rec => rec.meta.requiresAuth))
if (user)
next()
else
next(
name: 'login'
)
else if (to.matched.some(rec => rec.meta.alreadyAuth))
if (user)
next(
name: 'user'
)
else
next()
else
next()
)
export default router
还有一个问题是,当我通过身份验证并刷新用户组件时,它会将我重定向回登录组件。为什么会这样?
提前致谢
【问题讨论】:
【参考方案1】:因为我不知道你的main.js
这只是一个假设,但我认为currentUser
是undefined
。您应该记录 user
并检查它是否在页面加载时定义。 Firebase 的行为是异步的,因此为了准备好一切,您需要将整个应用程序包装在 firebase 回调中。
firebase.auth().onAuthStateChanged(() =>
new Vue(
router,
render: h => h(App)
).$mount('#app');
);
否则currentUser
可能还没有初始化。
【讨论】:
【参考方案2】:因此,您希望阻止已登录的用户访问您的登录路径,但您还希望阻止未登录的用户访问您的 Vue 应用程序中的某些页面。非常标准的用例。以下是我的实现方式:
首先,我的路线有元标记requiresAuth
和forVisitors
。如果用户登录并尝试访问 forVisitors 路由,我会将用户返回到主页(在下面的示例中为routeObject.path = '/'
)。如果用户未登录并尝试访问requiresAuth
路径,我会将他们踢到/login。我发现这种方法对于路线构建非常灵活。
我的路由器需要知道什么是登录用户。使用 Firebase 的 auth 模块,我可以订阅 onAuthStateChanged
并确定用户是否从第一次发射开始登录。
注意,我将当前用户存储在 VueX 存储 (store.state.userModule.user
) 中,如果不这样做,您可以忽略该位。此外,我将 Firebase Auth 对象存储为 store.state.userModule.auth
,因此当您看到它时,它与 Firebase auth 相同。
此外,您可以在此处找到有关我将 onAuthStateChanged 订阅包装在 Promise 中的更多详细信息:Getting 'Uncaught' after catching error in firebase.auth() with async
const router = new Router(
/* example of forVisitors path */
path: '/Login',
name: 'Login',
component: Login,
meta:
requiresAuth: false,
forVisitors: true
,
/* example of requiresAuth path */
path: '/Submit/:mode?/:primary?/:secondary?',
name: 'Submit',
component: Submit,
props: true,
meta:
requiresAuth: true
);
router.beforeEach(async (to, from, next) =>
/* Check for a user in my store, or fallback to Firebase auth() user */
let currentUser =
store.state.userModule.user ||
(await new Promise((resolve) =>
store.state.userModule.auth().onAuthStateChanged(user =>
resolve(user);
);
));
const requiresAuth = to.meta.requiresAuth;
const forVisitors = to.meta.forVisitors;
const routeObject = ;
if (forVisitors && currentUser)
routeObject.path = '/';
else if (requiresAuth && !currentUser)
routeObject.path = '/login';
next(routeObject);
);
【讨论】:
以上是关于Vue.js:如何保护登录组件免受经过身份验证的用户的影响的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 IdentityServer4 保护 API(免受意外调用)?