Nuxt 2迁移Nuxt 3遇阻:认证中间件代码适配求助
Nuxt 3 适配修改方案
关键变化说明
Nuxt 3 不再提供全局 app 对象,需通过内置 Composables 获取资源,同时推荐使用 ofetch(内置轻量请求库)替代 Axios、用 Pinia 替代 Vuex 做状态管理。以下是你的认证中间件适配修改:
修改后的完整代码
1. 中间件文件(middleware/auth.js)
export default defineNuxtRouteMiddleware(async () => { try { console.log('Loading...'); const csrfToken = await fetchCsrfToken(); const authResult = await checkAuth("accessToken", csrfToken); // 调用 Pinia Store 更新状态 const authStore = useAuthStore(); authStore.setAuthResult(authResult?.res); if (authResult?.res) { const userInfo = await getUserInfo(csrfToken); authStore.setUserInfo(userInfo?.res); console.log(userInfo); } } catch (error) { console.error('Error during authentication check:', error); } }); // 封装请求逻辑(用内置 $fetch 替代 Axios) async function ajaxRequest(url, method, data) { const headers = { 'Content-Type': 'application/json', }; if (data) { data.token && (headers.Authorization = `Bearer ${data.token}`); data.csrfToken && (headers['X-XSRF-TOKEN'] = data.csrfToken); } try { return await $fetch(url, { method, headers, body: data }); } catch (error) { let errorMessage; switch (error.statusCode) { case 400: errorMessage = `Bad Request: ${error.data}`; break; case 401: errorMessage = `Unauthorized: ${error.data}`; break; case 403: errorMessage = `Forbidden: ${error.data}`; break; default: errorMessage = `Request failed with status: ${error.statusCode}`; } throw new Error(errorMessage); } } // 获取 CSRF Token async function fetchCsrfToken() { try { const response = await $fetch('/getcsrf'); console.log('CSRF token stored in Cookies:', response.token); return response.token; } catch (error) { console.error('Error fetching CSRF token:', error); throw error; } } // 校验认证状态 async function checkAuth(tokenType, csrfToken) { let token; if (tokenType === 'accessToken') { token = useCookie('accessToken').value; } else if (tokenType === 'refreshToken') { token = useCookie('refreshToken').value; } else { console.error('Invalid tokenType:', tokenType); return; } try { console.log(`${tokenType} call`); const res = await ajaxRequest('/check-auth', 'POST', { token, csrfToken }); if (tokenType === 'accessToken' && res === 'Refresh token required') { await checkAuth('refreshToken', csrfToken); return false; } return { res }; } catch (error) { console.error('Error checking authentication:', error); } } // 获取用户信息 async function getUserInfo(csrfToken) { const token = useCookie('accessToken').value; try { const res = await ajaxRequest("/user-info", "POST", { token, csrfToken }); return { res }; } catch (error) { console.error('Error fetching user info:', error); } }
2. Pinia 状态管理文件(stores/auth.js)
Nuxt 3 推荐用 Pinia 替代 Vuex,需先安装 @pinia/nuxt 依赖,然后创建状态文件:
export const useAuthStore = defineStore('auth', { state: () => ({ authResult: null, userInfo: null }), actions: { setAuthResult(result) { this.authResult = result; }, setUserInfo(info) { this.userInfo = info; } } });
核心修改点
- 中间件定义:用
defineNuxtRouteMiddleware替代原函数,不再接收app参数 - 请求库替换:用 Nuxt 内置的
$fetch替代app.$axios,无需额外配置 - Cookie 操作:用
useCookieComposable 替代app.$cookies,自动兼容客户端/服务端 - 状态管理:用 Pinia 的 Store 方法替代 Vuex 的
store.commit
内容的提问来源于stack exchange,提问作者JunYoungMoon
相关产品推荐
相关产品推荐

