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

Next.js部署Vercel后环境变量失效:缺失client_email字段报错

问题:Vercel部署后Google Sheets API认证失败(client_email缺失)

我开发了一个企业落地页项目,内含两个表单,用户输入的数据会提交至Google Sheets。本地测试时功能正常,数据可成功写入表格,但将代码部署到Vercel并导入.env文件配置环境变量后,出现报错:

Error: The incoming JSON object does not contain a client_email field
    at i.fromJSON (/var/task/.next/server/chunks/157.js:13:43873)
    at R.fromJSON (/var/task/.next/server/chunks/157.js:13:29063)
    at R._cacheClientFromJSON (/var/task/.next/server/chunks/157.js:13:29139)
    at R.getClient (/var/task/.next/server/chunks/157.js:13:31724)
    at l (/var/task/.next/server/app/api/send-data/route.js:1:2072)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:34666
    at async eS.execute (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:25813)
    at async eS.handle (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:35920)
    at async es (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:25461)

项目中/api/send-data/route.ts代码如下:

import { NextResponse, NextRequest } from "next/server";
import { google } from "googleapis";

const credentials = {
  type: process.env.TYPE,
  project_id: process.env.PROJECT_ID,
  private_key_id: process.env.PRIVATE_KEY_ID,
  private_key: process.env.PRIVATE_KEY,
  client_email: process.env.CLIENT_EMAIL,
  client_id: process.env.CLIENT_ID,
  auth_uri: process.env.AUTH_URI,
  token_uri: process.env.TOKEN_URI,
  auth_provider_x509_cert_url: process.env.AUTH_PROVIDER_X509_CERT_URL,
  client_x509_cert_url: process.env.CLIENT_X509_CERT_URL,
  universe_domain: process.env.UNIVERSE_DOMAIN,
};

const auth = new google.auth.GoogleAuth({
  credentials: credentials,
  scopes: ["https://www.googleapis.com/auth/spreadsheets"],
});

const spreadsheetId = "1Tt03EVfbBKL_31iIC82VNDbti7ZvIbIlYoXYqon5Q8c"; 

export const POST = async (request: NextRequest) => {
  try {
    const { name, email, phone, comment } = await request.json();

    // Validate fields
    if (!name || !email || !phone || !comment) {
      return NextResponse.json({
        message: "Por favor complete todos los campos",
      });
    }

    // Create client
    const authClient = (await auth.getClient()) as any;

    // Instance of Google Sheets API
    const googleSheets = google.sheets({ version: "v4", auth: authClient });

    // Get metadata about spreadsheet
    const metaData = await googleSheets.spreadsheets.get({
      auth: auth,
      spreadsheetId: spreadsheetId,
    });

    // Upload data onto the spreadsheet
    await googleSheets.spreadsheets.values.append({
      spreadsheetId,
      range: "hoja principal!A:D",
      valueInputOption: "USER_ENTERED",
      requestBody: {
        values: [[name, email, phone, comment]],
      },
    });

    return NextResponse.json({
      message: metaData.data,
    });
  } catch (error) {
    console.error(error);
    return NextResponse.json({
      status: "404",
      message: "There was an error",
    });
  }
};

另一个/api/programs-data/route.ts逻辑相同,但使用不同字段和环境变量。有人建议给环境变量添加NEXT_PUBLIC_前缀,但因变量包含私钥等敏感信息,我担心安全问题,想请教该问题的原因及解决办法。


原因分析与解决办法

核心原因

  1. Vercel环境变量未正确配置:本地.env里的变量在Vercel中可能存在拼写错误、字段遗漏,导致client_email等关键认证字段为undefined,Google Auth库解析时抛出缺失字段的错误。
  2. 私钥格式错误:PRIVATE_KEY在Vercel中配置时丢失了换行格式(比如本地的\n转义字符未保留),导致整个credentials对象无效,间接触发client_email的错误提示。
  3. 对NEXT_PUBLIC_前缀的误解:这个前缀是让环境变量暴露给前端代码的,而你的API路由运行在服务端,完全不需要加这个前缀,加了反而会泄露敏感信息,绝对不可取。

解决步骤

  1. 核对Vercel环境变量

    • 进入Vercel项目的Settings → Environment Variables页面,逐一比对所有Google认证相关变量的名称、内容,确保和本地.env完全一致(注意变量名大小写敏感),重点确认CLIENT_EMAIL字段已正确添加。
    • 确保所有变量都已设置,没有遗漏任何credentials中的字段。
  2. 正确配置PRIVATE_KEY

    • 本地.env中的私钥通常包含\n转义字符,在Vercel中配置时,要么直接粘贴原始私钥(保留真实换行),要么保留\n转义格式。比如私钥开头是-----BEGIN PRIVATE KEY-----\n,结尾是\n-----END PRIVATE KEY-----,必须完整配置。
  3. 验证环境变量加载情况

    • 在API路由中临时添加日志代码,部署后查看Vercel函数日志(Functions → Logs),确认变量是否正常获取:
      console.log("CLIENT_EMAIL:", process.env.CLIENT_EMAIL);
      console.log("Credentials Object:", credentials);
      
    • 如果输出为undefined,说明变量配置有误,重新检查Vercel的环境变量设置。
  4. 服务端环境变量的正确用法

    • 服务端路由(app/api下的文件)直接使用process.env.XXX即可,绝对不能给敏感变量加NEXT_PUBLIC_前缀——这个前缀仅用于前端组件需要访问的非敏感变量,私钥、client_email这类信息一旦加前缀就会暴露给所有用户。

内容的提问来源于stack exchange,提问作者José andres Guzman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:32:04