Nuxt3 SSR场景下如何利用Cookie中的Auth Token请求服务器?
Nuxt3 SSR 应用认证与数据获取问题
我正在学习Nuxt3并开发SSR应用,使用@sidebase/nuxt-auth插件实现登录,该插件会自动将Token存储在Cookie中;数据获取使用nuxt-jsonapi插件。
当前遇到的问题:通过应用内导航进入交易列表页时能正常获取服务器数据,但刷新页面时,server/api/transations.ts中因无法获取Token导致500错误。
组件代码(DescktopTransactions.vue)
<script setup lang="ts"> ... const result = await $fetch('/api/transactions', { headers: { Authorization: `Bearer ${token}`, }, }); console.log('result', result); ... </script> <template> <v-data-table-server v-if="!transactionsStore.loading && transactionsStore.transactions.length" v-model:items-per-page="transactionsStore.itemsPerPage" :headers="headers" :items="transactionsStore.transactions" :items-length="transactionsStore.totalItems" item-value="id" :page.sync="transactionsStore.page" hide-default-footer class="transactions__table" > ... </template>
API路由代码(server/api/transations.ts)
import { defineEventHandler, getHeader } from 'h3'; import axios from 'axios'; export default defineEventHandler(async (event) => { const config = useRuntimeConfig(); const apiURL = `${config.public.protocol}${config.public.domain}:${config.public.port}${config.public.apiPath}`; const authorization = getHeader(event, 'Authorization'); if (!authorization) { throw createError({ statusCode: 401, statusMessage: 'Unauthorized', }); } const response = await axios.get(`${apiURL}/purchases`, { headers: { Authorization: authorization, Accept: 'application/vnd.api+json', 'Content-Type': 'application/vnd.api+json', 'Accept-Language': 'en', }, }); return JSON.stringify(response.data.data); });
疑问与解答
1. 是否有其他方式从Cookie传递Token?
有。@sidebase/nuxt-auth已将Token存储在Cookie中,在SSR的API路由里,可直接从请求Cookie中提取Token,无需依赖前端传入的Authorization头。
修改server/api/transations.ts,用getCookie替代getHeader:
import { defineEventHandler, getCookie } from 'h3'; import axios from 'axios'; export default defineEventHandler(async (event) => { const config = useRuntimeConfig(); const apiURL = `${config.public.protocol}${config.public.domain}:${config.public.port}${config.public.apiPath}`; // 替换为@sidebase/nuxt-auth实际存储Token的Cookie名称 const token = getCookie(event, 'auth-token'); if (!token) { throw createError({ statusCode: 401, statusMessage: 'Unauthorized', }); } const response = await axios.get(`${apiURL}/purchases`, { headers: { Authorization: `Bearer ${token}`, Accept: 'application/vnd.api+json', 'Content-Type': 'application/vnd.api+json', 'Accept-Language': 'en', }, }); return JSON.stringify(response.data.data); });
注意需确认@sidebase/nuxt-auth的Cookie名称,可通过插件配置或浏览器开发者工具查看实际Cookie键名。
2. 是否无需当前方式,直接在组件或Pinia中请求服务器即可?
可以,但需区分场景:
- 客户端导航:直接在组件/Pinia中调用后端API可行,但需处理跨域——要么在
nuxt.config.ts配置代理,要么后端配置CORS允许Nuxt前端域名访问。 - SSR刷新场景:在组件的
useAsyncData中直接请求后端API,Nuxt会在服务器端发起请求,此时浏览器的Cookie会自动传递到服务器端请求(需确保Cookie的SameSite和domain配置正确),同时后端要允许Nuxt服务器的域名访问。
当前用Nuxt API路由作为中间层的优势是隐藏后端真实地址、统一处理认证逻辑,若保留该模式,建议用Cookie提取Token的方式修复问题;若想简化流程,也可直接在组件中用useAsyncData结合$fetch请求后端。
3. 前后端跨域场景下,哪些情况适合使用SSR?
以下场景优先选择SSR:
- SEO需求强烈:页面内容需被搜索引擎爬虫抓取,SSR直接返回渲染完成的HTML,比SPA更利于SEO。
- 首屏性能要求高:SSR在服务器端提前渲染页面内容,减少客户端加载等待时间,提升首屏速度。
- 敏感逻辑处理:认证、权限校验等敏感操作放在服务器端执行,避免在客户端暴露敏感代码或凭证。
- 统一数据获取:无论客户端导航还是页面刷新,都能在服务器端统一处理数据请求,复用逻辑,且服务器端请求不受浏览器CORS限制,无需额外配置跨域。
如果应用以交互为主(如后台管理系统)、对SEO和首屏速度要求不高,SPA模式会更简单;但满足上述任一需求时,SSR仍是合适的选择。
内容的提问来源于stack exchange,提问作者Kirill Donenko
相关产品推荐
相关产品推荐

