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

Next.js中如何在_app文件中安全隐藏并使用环境变量?

客户端安全使用环境变量的方案

一、核心原则先明确

  • 任何直接暴露给客户端的环境变量,最终都会被打包进前端代码,不存在客户端层面的保密可能。真正需要保密的密钥、API密钥等敏感信息,必须只在服务端(比如getServerSideProps、API路由、Server Components)中使用。
  • _app.js无法使用getServerSideProps,但可以通过其他方式传递服务端处理后的安全数据,或合理区分环境变量的使用场景。

二、具体实现方案

1. 区分环境变量类型

  • 服务端专用变量:无需前缀(比如SECRET_API_KEY),这类变量只会在服务端代码加载,永远不会暴露给客户端。
  • 客户端可访问变量:必须添加NEXT_PUBLIC_前缀(比如NEXT_PUBLIC_API_BASE_URL),构建时会注入客户端代码,适合存放非敏感配置(如公开API地址、第三方公开ID)。

2. 给客户端传递服务端处理后的安全数据

如果业务需要将服务端处理后的非敏感数据(而非原始密钥)传给客户端,比如用户授权令牌,可通过两种方式实现:

  • 页面getServerSideProps传递数据:每个页面的getServerSideProps可在服务端获取数据后,通过props传递给页面,_app.js能通过pageProps拿到这些数据。
    示例代码:
    // pages/some-page.js
    export async function getServerSideProps(context) {
      // 服务端访问保密环境变量
      const secretKey = process.env.SECRET_API_KEY;
      // 用密钥请求数据,返回非敏感结果(如用户信息)
      const userData = await fetch(`https://api.example.com/user`, {
        headers: { Authorization: `Bearer ${secretKey}` }
      }).then(res => res.json());
    
      return { props: { userData } };
    }
    
    // 页面组件接收props,_app可通过pageProps获取
    export default function SomePage({ userData }) {
      return <div>Hello {userData.name}</div>;
    }
    
  • API路由做中转:将需要保密的操作放到pages/api/下的路由中,客户端调用该API路由,由服务端使用环境变量处理请求后返回结果。
    示例代码:
    // pages/api/get-user.js
    export default async function handler(req, res) {
      // 服务端访问保密变量
      const secretKey = process.env.SECRET_API_KEY;
      const userData = await fetch(`https://api.example.com/user`, {
        headers: { Authorization: `Bearer ${secretKey}` }
      }).then(res => res.json());
      
      res.status(200).json(userData);
    }
    
    // 客户端组件(包括_app)调用该API
    async function fetchUserData() {
      const res = await fetch('/api/get-user');
      const data = await res.json();
      return data;
    }
    

3. 在_app.js中使用服务端数据

_app.js的pageProps包含所有页面getServerSideProps返回的参数,也可通过useEffect调用API路由获取数据:

// pages/_app.js
function MyApp({ Component, pageProps }) {
  // 直接使用pageProps中的服务端数据
  // 或通过useEffect调用API获取数据
  useEffect(() => {
    async function loadData() {
      const data = await fetch('/api/get-user').then(res => res.json());
      // 处理数据逻辑
    }
    loadData();
  }, []);

  return <Component {...pageProps} />;
}

export default MyApp;

三、关键提醒

  • 绝对不要将无NEXT_PUBLIC_前缀的保密变量(如原始密钥)放到客户端代码中,哪怕通过props传递,也会被暴露。
  • 不确定变量是否敏感时,默认只在服务端使用,通过API路由做中转处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:05:17