Vue3+Pinia+Vue-Router路由守卫早于Pinia Store加载的问题
问题:基于Pinia Store实现路由守卫,禁止已登录用户访问登录/注册页
技术版本
vue@3.2.47 pinia@2.0.35 vue-router@4.1.6
当前认证逻辑实现
我使用Firebase做认证服务,通过Pinia Store管理认证状态,核心实现如下:
- 新建了
storeAuth.ts作为认证状态仓库,核心代码:
... export const useStoreAuth = defineStore('storeAuth', () => { const user = ref(null) const loading = ref(false) const errorMessage = ref("") const successMessage = ref("") const router = useRouter() const init = () => { onAuthStateChanged(auth, (firebaseUser) => { if (firebaseUser) { user.value = {} user.value.id = firebaseUser.uid user.value.email = firebaseUser.email console.log('logged in:',user); } else { user.value = null //console.log('logged out'); } }); } ... const loginUser = (credentials) => { successMessage.value = "" errorMessage.value = "" loading.value = true signInWithEmailAndPassword(auth, credentials.email, credentials.password).then((userCredential) => { loading.value = false const firebaseUser = userCredential.user; router.push('/') }).catch((error) => { loading.value = false //console.log('Error while logging in:',error.message); switch (error.code) { case 'auth/user-not-found': errorMessage.value = "Email and/or password incorrect" break; case 'auth/wrong-password': errorMessage.value = "Email and/or password incorrect" break; case 'auth/too-many-requests': errorMessage.value = "Too many requests. Please reset your password" break; default: errorMessage.value = "There was an error during login" break; } }); } ...
- 登录流程通过调用
loginUser函数传入账号凭证完成。
需求与遇到的问题
需要实现路由守卫规则:已登录用户禁止访问登录(signin)、注册(register)页面。
尝试直接在router/index.ts中获取Pinia Store的user值,但始终返回null。于是改用直接从Firebase获取用户的方案,代码如下,但该方案无效:
let currentUser = null const getCurrentUser = async () => { return new Promise<void>((resolve) => { onAuthStateChanged(auth, (user) => { currentUser = user resolve() }) }) } const setupNavigationGuards = async () => { await getCurrentUser() router.beforeEach((to, from, next) => { currentUser = auth.currentUser if (currentUser && (to.name === 'signin' || to.name === 'register')) { next({ name: 'home' }) } else { next() } }) } // Call the setupNavigationGuards function setupNavigationGuards()
我更希望基于Pinia Store中的user状态来实现路由守卫,因为后续需要扩展角色字段,实现管理员菜单控制,而不是直接依赖Firebase的用户对象。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

