我正在嘗試使用具有 JWT 身份驗證的應用程式創建 Vue 3,并遇到使用 Pinia 商店中的“isAuth”變數來檢查訪問權限來保護路由器的問題。最終 Vue 路由器和應用程式的整體加載速度比商店快,這就是為什么我總是從商店獲得“未經授權”的價值,但實際上用戶已登錄并且他的資料在商店中。我將嘗試描述注冊和登錄用戶的所有步驟。
- 注冊到 NodeJS 后端并創建 JWT 令牌。
- 在登錄螢屏上,用戶輸入電子郵件和密碼,如果資訊有效,他將登錄,JWT 將保存到 localstorage 并通過 JWTdecode 解碼,解碼后的令牌資料將保存到用戶變數中的 store 中,并將 isAuth 變數設定為 true .
- Pinia 商店有 2 個處于狀態的欄位:user(最初為 null)和 isAuth(最初為 false)。
- 在主 App 組件中,我使用 async onMounted 鉤子檢查令牌并通過呼叫 API 方法保持用戶登錄,該方法比較 JWT。
- 在 Vue 路由器中,我有幾條必須防止未經授權的用戶訪問的路線,這就是為什么我試圖通過檢查商店中的用戶資訊來為它們創建導航保護。問題是,路由器是在設定用戶資訊后創建的,并且總是獲取用戶和 isAuth 變數的初始狀態。
代碼:
店鋪
import { defineStore } from 'pinia';
export const useLoggedInUserStore = defineStore({
id: 'loggedInUser',
state: () => ({
isAuth: false,
user: null
}),
getters: {
getisAuth(state) {
return state.isAuth;
},
getUser(state) {
return state.user;
}
},
actions: {
setUser(user) {
this.user = user;
},
setAuth(boolean) {
this.isAuth = boolean;
}
}
});
App.vue onMounted
onMounted(async () => {
await checkUser()
.then((data) => {
isLoading.value = true;
if (data) {
setUser(data);
setAuth(true);
} else {
router.push({ name: 'Login' });
}
})
.finally((isLoading.value = false));
});
路由器保護示例
router.beforeEach((to, from, next) => {
const store = useLoggedInUserStore();
if (!store.isAuth && to.name !== 'Login') next({ name: 'Login' });
else next();
});
我覺得這個異步檢查存在問題,但無法弄清楚如何在應用程式初始化之前重寫它以加載存盤。
我希望有人也遇到這個問題并且可以提供幫助。
提前致謝!
uj5u.com熱心網友回復:
所以我剛剛遇到了這個問題并通過這個解決方案解決了它
正如它所說,路由器在App.vue完全安裝之前被實體化,因此請檢查令牌beforeEach,例如:
router.beforeEach(async (to, from, next): Promise<void> => {
const user = useUser();
await user.get();
console.log(user) // user is defined
if (to.meta.requiresAuth && !user.isLoggedIn) next({ name: "home" }); // this will work
順便說一句,setAuth您可以使用 getterisAuth檢查是否user不為空,而不是采取行動,例如:
isAuth: (state) => state.user !== null
此外,不建議將 JWT 存盤在本地存盤中,因為如果您的站點受到 XSS 攻擊,令牌可能會被盜。您至少應該將它存盤在 HttpOnly cookie 中(這意味著它不能從 JavaScript 訪問),使用 Express 非常容易。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/456380.html
上一篇:如何以及何時使用重繪令牌?
