
在next.js项目中,环境变量的管理是构建可配置应用的关键。next.js对环境变量的处理方式进行了区分,以确保安全性和灵活性:
许多开发者在本地开发时,会将所有环境变量都定义在.env.local文件中,并且由于本地开发服务器的行为,即使是带有NEXT_PUBLIC_前缀的变量,在服务器端API路由中也可能意外地被访问到。然而,一旦部署到生产环境,这种行为就会发生变化。
原始问题中,Google Sheets API的凭据(NEXT_PUBLIC_GOOGLE_CLIENT_EMAIL和NEXT_PUBLIC_GOOGLE_PRIVATE_KEY)被错误地使用了NEXT_PUBLIC_前缀。这些凭据是用于服务器端与Google API进行认证的敏感信息,本应只在服务器端API路由中访问。当它们被定义为NEXT_PUBLIC_时,Next.js在构建时会尝试将它们暴露给客户端,但由于它们是敏感的,或者在生产构建流程中处理方式不同,最终导致在服务器端API路由中无法正确读取,从而引发“The incoming JSON object does not contain a client_email field”之类的错误。
即使环境变量通过AWS等云服务注入,如果命名约定不符合Next.js的规范,或者在服务器端代码中试图以客户端变量的方式访问服务器端秘密,问题依然会出现。
对于只应在服务器端使用的敏感信息,绝不能使用NEXT_PUBLIC_前缀。
示例:
假设你的Google API凭据需要用于Next.js的API路由(pages/api/submit.js),它们应该这样定义在你的.env或生产环境配置中:
# .env 或生产环境配置 GOOGLE_CLIENT_EMAIL=your-client-email@example.com GOOGLE_PRIVATE_KEY=-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY----- GOOGLE_SHEET_ID=your-sheet-id
然后在你的API路由中,你可以直接通过process.env访问它们:
// pages/api/submit.js
import { google } from 'googleapis';
export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).send('Only POST requests are allowed!');
  }
  try {
    const auth = new google.auth.GoogleAuth({
      credentials: {
        client_email: process.env.GOOGLE_CLIENT_EMAIL, // 注意:不再有 NEXT_PUBLIC_ 前缀
        private_key: process.env.GOOGLE_PRIVATE_KEY?.replace(/\n/g, '
'),
      },
      scopes: [
        'https://www.googleapis.com/auth/drive',
        'https://www.googleapis.com/auth/drive.file',
        'https://www.googleapis.com/auth/spreadsheets',
      ],
    });
    // ... 后续逻辑
    return res.status(201).json({ data: response.data });
  } catch (error) {
    console.error('API submission error:', error);
    return res.status(error.code || 500).send({ message: error.message || 'An unknown error occurred.' });
  }
}注意事项:
有时,即使是带有NEXT_PUBLIC_前缀的变量(例如Google Tag Manager ID),也可能在某些生产部署环境中无法正确加载。这通常发生在客户端代码尝试访问这些变量时。为了确保这些公共变量在客户端可用,并且避免直接在构建时硬编码可能带来的问题(例如,需要动态切换环境配置),可以创建一个API路由来专门暴露这些公共环境变量。
示例:
创建一个API路由,例如pages/api/env.js,用于返回所有以NEXT_PUBLIC_开头的环境变量:
// pages/api/env.js
export default function handler(req, res) {
  // 过滤出所有以 'NEXT_PUBLIC_' 开头的环境变量
  const publicEnv = Object.keys(process.env)
    .filter((key) => key.startsWith('NEXT_PUBLIC_'))
    .reduce((acc, key) => {
      acc[key] = process.env[key];
      return acc;
    }, {});
  // 返回这些公共环境变量
  res.status(200).json(publicEnv);
}然后在客户端组件中,你可以通过fetch请求这个API路由来获取公共环境变量:
// components/MyClientComponent.js (或任何需要客户端环境变量的地方)
import React, { useEffect, useState } from 'react';
function MyClientComponent() {
  const [envConfig, setEnvConfig] = useState({});
  useEffect(() => {
    async function fetchEnv() {
      try {
        const response = await fetch('/api/env'); // 请求你创建的API路由
        const data = await response.json();
        setEnvConfig(data);
      } catch (error) {
        console.error('Failed to fetch public environment variables:', error);
      }
    }
    fetchEnv();
  }, []);
  // 现在你可以通过 envConfig 访问这些变量,例如:
  // const gtmId = envConfig.NEXT_PUBLIC_GTM_ID;
  return (
    <div>
      {envConfig.NEXT_PUBLIC_GTM_ID ? (
        <p>Google Tag Manager ID: {envConfig.NEXT_PUBLIC_GTM_ID}</p>
      ) : (
        <p>Loading GTM ID...</p>
      )}
    </div>
  );
}
export default MyClientComponent;注意事项:
Next.js环境变量的正确使用是确保应用在生产环境中稳定运行的关键。核心原则是:
遵循这些最佳实践,可以有效避免在生产环境中因环境变量配置不当而导致的“秘密值不可见”问题。
以上就是掌握Next.js生产环境中的环境变量:避免秘密值不可见的陷阱的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号