You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt.js服务端获取存储Bearer Token遇FS模块引入问题求助

解决Nuxt ServerMiddleware中无法引入fs模块的问题及Bearer Token存储最佳实践

首先,咱们来拆解你遇到的核心问题:你明明把代码放在serverMiddleware里,却还是碰到了fs模块找不到的报错,这是因为文件位置和Nuxt的默认处理逻辑不匹配。根目录下的middleware文件夹是页面级中间件的默认位置,Nuxt会默认把这里的代码同时打包给客户端和服务端——而客户端浏览器根本没有fs模块,自然就报错了。

第一步:修正ServerMiddleware的文件位置与配置

Nuxt专门为服务端中间件提供了server/middleware目录(如果没有就手动创建),把你的bearerToken.ts移到这个目录下,Nuxt会明确将其标记为仅服务端运行的代码,不会打包到客户端。

修改后的nuxt.config.ts配置可以简化成这样:

export default defineNuxtConfig({
  serverMiddleware: [
    // 直接指定路径,Nuxt会自动识别为服务端中间件
    '~/server/middleware/bearerToken.ts'
    // 或者更明确的对象配置(可选)
    // { path: '/', handler: '~/server/middleware/bearerToken.ts', mode: 'server' }
  ]
})

第二步:修正中间件代码中的fs引入逻辑

在TypeScript里建议用ES模块的import方式引入fs,同时加上process.server的判断(虽然放在server/middleware里已经是服务端专属,但加一层判断更稳妥):

import type { IncomingMessage, ServerResponse } from 'http'
import fs from 'fs'
import path from 'path'

export default function bearerTokenMiddleware(req: IncomingMessage, res: ServerResponse, next: () => void) {
  try {
    // 确保只在服务端执行文件操作
    if (process.server) {
      // 建议把Token文件放在项目根目录的专属文件夹里,避免和源码混在一起
      const tokenDir = path.resolve(process.cwd(), '.nuxt', 'tokens')
      const tokenPath = path.join(tokenDir, 'bearer.token')

      // 先创建目录(避免文件写入时目录不存在报错)
      if (!fs.existsSync(tokenDir)) {
        fs.mkdirSync(tokenDir, { recursive: true })
      }

      // 这里写你的Token读取/生成逻辑
      if (fs.existsSync(tokenPath)) {
        const existingToken = fs.readFileSync(tokenPath, 'utf-8')
        // 可以把Token挂载到req对象上,方便后续API请求使用
        (req as any).bearerToken = existingToken
      } else {
        // 调用OAuth令牌端点获取新Token的逻辑
        // 比如用axios请求:
        // const tokenResponse = await axios.post('https://your-oauth-endpoint/token', {
        //   client_id: 'YOUR_CLIENT_ID',
        //   client_secret: 'YOUR_CLIENT_SECRET',
        //   grant_type: 'client_credentials'
        // })
        // const newToken = tokenResponse.data.access_token
        // fs.writeFileSync(tokenPath, newToken, 'utf-8')
        // (req as any).bearerToken = newToken
      }
    }
  } catch (e) {
    console.error('处理Bearer Token时发生错误:', e)
  }
  next()
}

第三步:关于Bearer Token存储的最佳实践

你当前用本地文件存储Token的方案,在单实例开发环境下可以用,但生产环境有明显缺陷:

  • 如果是多实例部署(比如Docker集群、云服务器多节点),每个实例的文件系统独立,Token无法共享,会导致重复请求OAuth端点,容易触发限流。
  • 文件存储没有自动过期机制,需要手动处理Token的刷新逻辑。

更推荐的生产级方案:

  • 分布式缓存(如Redis):所有服务实例共享Token,配合过期时间自动刷新,是最稳妥的方案。Nuxt 3可以通过useStorage配置Redis驱动,直接调用缓存API。
  • 服务端内存缓存:适合单实例部署,用Node.js的Map或第三方缓存库(如lru-cache)存储Token,加上过期时间,每次请求前检查是否过期,过期则重新获取。
  • Nuxt内置存储:Nuxt 3的useStorage默认支持内存存储,开发时可以快速上手,生产环境再切换到Redis。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:25:18