Nuxt3集成Auth0遇SSR兼容问题:document未定义报错求助
问题背景
我正尝试在Nuxt3应用中集成Auth0,但不知该如何正确实现。目前auth-nuxt模块暂不支持Nuxt3,而auth0-spa-js无法在SSR环境下正常工作。我编写了以下代码:
Auth0初始化代码(authfile.js)
import createAuth0Client from "@auth0/auth0-spa-js"; let auth = await createAuth0Client({ domain: "dev-......com", client_id: "Z0...................0T6I", redirect_uri: '<MY_CALLBACK_URL>' }); export default auth;
路由中间件代码
import auth from "../store/authfile"; export default defineNuxtRouteMiddleware(async (to, from) => { let isAuthenticated = await auth.isAuthenticated(); if (to.path === "/" && !to?.query?.code) { return; } if (!isAuthenticated) { const query = to?.query; if (query && query.code && query.state) { await auth.handleRedirectCallback(); } else { await auth.loginWithRedirect(); } } else { console.log("logged in ", to.path); } const router = useRouter(); if (to.path === "/") { to.fullPath = "/"; } navigateTo(to.path); });
错误信息
500 document is not defined
at getAll (C:\Users\vesel\Desktop\nuxt-app\node_modules\es-cookie\src\es-cookie.js:68:18)
at Object.get (C:\Users\vesel\Desktop\nuxt-app\node_modules\es-cookie\src\es-cookie.js:72:12)
at Object.get (C:\Users\vesel\Desktop\nuxt-app\node_modules@auth0\auth0-spa-js\dist\lib\auth0-spa-js.cjs.js:4550:40)
at Object.get (C:\Users\vesel\Desktop\nuxt-app\node_modules@auth0\auth0-spa-js\dist\lib\auth0-spa-js.cjs.js:4585:35)
at Auth0Client. (C:\Users\vesel\Desktop\nuxt-app\node_modules@auth0\auth0-spa-js\dist\lib\auth0-spa-js.cjs.js:5258:45)
at step (C:\Users\vesel\Desktop\nuxt-app\node_modules@auth0\auth0-spa-js\dist\lib\auth0-spa-js.cjs.js:186:23)
at Object.next (C:\Users\vesel\Desktop\nuxt-app\node_modules@auth0\auth0-spa-js\dist\lib\auth0-spa-js.cjs.js:130:20)
at C:\Users\vesel\Desktop\nuxt-app\node_modules@auth0\auth0-spa-js\dist\lib\auth0-spa-js.cjs.js:107:71
at new Promise ()
at __awaiter (C:\Users\vesel\Desktop\nuxt-app\node_modules@auth0\auth0-spa-js\dist\lib\auth0-spa-js.cjs.js:89:12)
解决方案
错误核心是auth0-spa-js依赖浏览器环境的document对象操作cookie,但Nuxt3的SSR阶段运行在Node.js环境,没有document,因此需要限制Auth0相关代码仅在客户端执行。
1. 调整Auth0初始化逻辑
修改authfile.js,仅在客户端初始化Auth0 Client:
import createAuth0Client from "@auth0/auth0-spa-js"; let auth; export const getAuth0Client = async () => { // 仅在客户端环境初始化 if (process.client && !auth) { auth = await createAuth0Client({ domain: "dev-......com", client_id: "Z0...................0T6I", redirect_uri: '<MY_CALLBACK_URL>' }); } return auth; };
2. 修改路由中间件,仅在客户端执行Auth0操作
import { getAuth0Client } from "../store/authfile"; export default defineNuxtRouteMiddleware(async (to, from) => { // SSR阶段直接返回,不执行Auth0逻辑 if (!process.client) return; const auth = await getAuth0Client(); const isAuthenticated = await auth.isAuthenticated(); if (to.path === "/" && !to?.query?.code) { return; } if (!isAuthenticated) { const query = to?.query; if (query && query.code && query.state) { await auth.handleRedirectCallback(); return navigateTo(to.path); } else { await auth.loginWithRedirect({ redirect_uri: window.location.origin + to.path }); } } else { console.log("logged in ", to.path); } });
3. 更规范的方式:使用Nuxt3客户端插件
创建plugins/auth0.client.js(文件名带.client后缀,Nuxt会自动识别为客户端插件):
import createAuth0Client from "@auth0/auth0-spa-js"; export default defineNuxtPlugin(async () => { const auth0Client = await createAuth0Client({ domain: "dev-......com", client_id: "Z0...................0T6I", redirect_uri: window.location.origin + '/callback' // 替换为你的回调地址 }); return { provide: { auth0: auth0Client } }; });
然后在路由中间件中使用插件提供的实例:
export default defineNuxtRouteMiddleware(async (to, from) => { if (!process.client) return; const { $auth0 } = useNuxtApp(); const isAuthenticated = await $auth0.isAuthenticated(); // 后续逻辑同步骤2 });
4. 处理回调页面
创建pages/callback.vue,确保在客户端处理回调:
<script setup> const { $auth0 } = useNuxtApp(); onMounted(async () => { await $auth0.handleRedirectCallback(); navigateTo('/'); // 跳转到主页或目标页面 }); </script>
内容的提问来源于stack exchange,提问作者Veselin

