如何让部署在Firebase App Hosting的Next.js环境变量仅服务端访问
解决Firebase App Hosting + Next.js 服务端专属环境变量配置问题
要实现仅在Next.js服务端(服务器组件、API路由、中间件等请求时运行的代码)可用,绝对不发送到浏览器的环境变量配置,你需要调整apphosting.yaml中的availability规则,同时遵循Next.js的环境变量规范:
正确配置示例
env: - variable: MY_SECRET secret: MY_SECRET availability: - REQUEST
为什么之前的配置出问题?
1. 无availability的默认配置
Firebase App Hosting默认会让变量在构建阶段和请求运行阶段都可用。此时如果你的代码中存在不当操作(比如客户端组件误引用了process.env.MY_SECRET),或者Next.js在构建时误处理了变量,就会导致敏感值泄露到浏览器。
2. 仅设置BUILD可用性
服务器组件是在请求处理阶段动态渲染的,而BUILD仅让变量在构建过程中存在,请求运行时环境中没有该变量,所以访问process.env.MY_SECRET会抛出未定义错误,触发500。
3. 同时配置NEXT_PUBLIC_和普通变量
NEXT_PUBLIC_MY_SECRET的行为符合预期,因为前缀会告诉Next.js将其打包到客户端;- 普通
MY_SECRET的两个问题:- 被服务器组件写入HTML:这是代码逻辑问题——如果你在服务器组件中直接把
process.env.MY_SECRET的值渲染到页面(比如<div>{process.env.MY_SECRET}</div>),敏感值自然会出现在静态HTML里,和配置无关; - 客户端组件水化后移除:大概率是因为你的客户端代码中存在对
process.env.MY_SECRET的引用,构建时Next.js会将其替换为undefined,但Firebase在初始化时可能临时注入了变量, hydration 后React修正为undefined才消失。
- 被服务器组件写入HTML:这是代码逻辑问题——如果你在服务器组件中直接把
额外注意事项
- 绝对不要在客户端组件中引用不带
NEXT_PUBLIC_前缀的变量,哪怕只是判断是否存在也不行,否则Next.js可能会在构建时尝试处理该变量,导致意外泄露; - 服务器组件中切勿将敏感变量直接输出到HTML文本中,这是基础的代码安全规范;
- 如果需要在构建阶段也使用该变量(比如生成静态内容),可以设置
availability: [BUILD, REQUEST],但要确保构建时的使用不会导致变量被打包到客户端。
内容的提问来源于stack exchange,提问作者Félix Paradis
相关产品推荐
相关产品推荐

