我正在尝试检查 Vue 3 js 应用程序中的路由授权。这个想法是应该根据用户的角色(NavGuard)来定义授权。因此,当用户登录(JWT 令牌)时,我将他的角色添加到 Pinia 商店(useUserStore)的状态中。
我已经阅读了有关“在组件之外使用商店”的文档,并且当用户登录并被重定向到主页时它实际上正在工作。如果我 console.log(store)
我可以看到用户的角色。
import NotFoundView from '@/views/public/NotFoundView.vue'
import { useUserStore } from '@/stores/user'
import pinia from "@/stores/store.js";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: AboutView
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFoundView
},
]
})
router.beforeEach(async (to, from) => {
const store = await useUserStore();
console.log(store.user)
})
export default router
Main.js
import { createApp } from 'vue'
import store from '@/stores/store'
import App from '@/App.vue'
import router from '@/router'
import axios from 'axios'
axios.defaults.baseURL = 'http://127.0.0.1:8000'
const app = createApp(App)
app.use(store)
app.use(router, axios)
router.isReady().then(() => {
app.mount("#app");
});
store.js
import { createPinia } from "pinia";
const pinia = createPinia();
export default pinia;
用户.js
import { defineStore } from 'pinia'
import axios from 'axios'
export const useUserStore = defineStore('user', {
id: 'user',
state: () => ({
user: {
isAuthenticated: false,
id: null,
name: null,
email: null,
access: null,
refresh: null,
role: null,
}
}),
actions: {
initStore() {
console.log('initStore')
if (localStorage.getItem('user.access')) {
this.user.access = localStorage.getItem('user.access')
this.user.refresh = localStorage.getItem('user.refresh')
this.user.id = localStorage.getItem('user.id')
this.user.name = localStorage.getItem('user.name')
this.user.email = localStorage.getItem('user.email')
this.user.isAuthenticated = true
this.refreshToken()
console.log('Initialized user:', this.user)
}
},
})
此代码正在工作,因为当用户登录时我具有正确的预期行为。但是我需要在每个页面之前检查用户角色,而不仅仅是在登录时检查。
有什么建议吗?
感谢您抽出时间阅读!
这是代码的修改版本,可以帮助您实现所需的行为:
更新您的路由器配置:
import { createRouter, createWebHistory } from 'vue-router';
import { useUserStore } from '@/stores/user';
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: AboutView
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFoundView
},
]
});
router.beforeEach(async (to, from, next) => {
const store = useUserStore();
await store.initStore(); // Make sure the user state is initialized.
// Now, you can access the user's role and perform authorization checks.
const userRole = store.user.role;
// You can implement your authorization logic here.
// For example, check if the userRole has access to the route.
// You can also handle cases like redirecting to a login page if not authenticated.
// For simplicity, let's assume all users can access all routes.
// Replace this with your actual authorization logic.
if (userRole !== null) {
next(); // Allow navigation.
} else {
// Redirect to a login page or show an unauthorized message.
// Modify this according to your application's requirements.
next('/login'); // Redirect to a login page if the user's role is not defined.
}
});
export default router;
更新您的 user.js 存储: 在您的 user.js 存储中,似乎您有一个 initStore 操作来初始化用户状态。您可以在应用程序启动时调用此操作,以确保在任何路线导航之前初始化用户状态。
// user.js
import { defineStore } from 'pinia';
import axios from 'axios';
export const useUserStore = defineStore('user', {
// ... (your existing state and actions)
actions: {
initStore() {
if (localStorage.getItem('user.access')) {
// ... (your existing code to initialize the user state)
}
}
}
});
通过执行这些步骤,您的 Vue 3 应用程序现在应该在每个页面导航之前正确检查用户的角色,甚至在登录后也是如此。请记住将 router.beforeEach 防护中的占位符逻辑替换为基于用户角色的实际授权检查。