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

React+Vite应用环境变量失效致AWS Cognito认证异常求助

问题:Vite构建React+AWS Cognito应用时环境变量无法正确加载

我用Vite构建集成AWS Cognito认证的React应用,遇到环境变量无法正确加载或访问的问题,AWS Cognito配置因构建时环境变量传递错误而失效。移除vite.config.ts中硬编码的fallback值后,应用无法运行,控制台报错:

Uncaught Error: Both UserPoolId and ClientId are required.
    at new CognitoUserPool2 (amazon-cognito-identity-js.js?v=6908fcf6:5140:13)
    at auth.ts:14:18

相关代码参考

auth.ts文件

import { 
  CognitoUserPool, 
  CognitoUser, 
  AuthenticationDetails,
  CognitoUserSession,
  CognitoUserAttribute
} from 'amazon-cognito-identity-js';

const poolData = {
  UserPoolId: import.meta.env.VITE_AWS_USER_POOL_ID,
  ClientId: import.meta.env.VITE_AWS_USER_POOL_WEB_CLIENT_ID
};

const userPool = new CognitoUserPool(poolData); // 报错指向的第14行

export const getCurrentUser = () => {
  return userPool.getCurrentUser();
};

export const isAuthenticated = async (): Promise<boolean> => {
  const user = getCurrentUser();
  if (!user) return false;

  return new Promise((resolve) => {
    user.getSession((err: Error | null, session: CognitoUserSession | null) => {
      if (err || !session || !session.isValid()) {
        resolve(false);
        return;
      }
      resolve(true);
    });
  });
};

export const signIn = (email: string, password: string): Promise<any> => {
  return new Promise((resolve, reject) => {
    const authenticationDetails = new AuthenticationDetails({
      Username: email,
      Password: password
    });

    const cognitoUser = new CognitoUser({
      Username: email,
      Pool: userPool
    });

    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: (result) => {
        resolve(result);
      },
      onFailure: (err) => {
        reject(err);
      }
    });
  });
};

// 其余认证函数:signOut、signUp、confirmRegistration等代码省略

vite.config.ts文件

import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import path from "path";

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');
  
  const poolConfig = {
    userPoolId: env.VITE_AWS_USER_POOL_ID || "my-user-pool-id", // 移除fallback后失效
    clientId: env.VITE_AWS_USER_POOL_WEB_CLIENT_ID || "my-web-client-id" // 移除fallback后失效
  };

  return {
    plugins: [react(), tailwindcss()],
    base: "/",
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./src"),
        './runtimeConfig': './runtimeConfig.browser',
      },
    },
    define: {
      'process.env': {},
      'import.meta.env.VITE_AWS_USER_POOL_ID': JSON.stringify(poolConfig.userPoolId),
      'import.meta.env.VITE_AWS_USER_POOL_WEB_CLIENT_ID': JSON.stringify(poolConfig.clientId),
      'import.meta.env.VITE_API_URL': JSON.stringify(env.VITE_API_URL),
      'import.meta.env.VITE_AWS_REGION': JSON.stringify(env.VITE_AWS_REGION),
      'import.meta.env.MODE': JSON.stringify(mode)
    }
  };
});

.env文件

VITE_AWS_USER_POOL_ID=us-east-1_myuserpoolid
VITE_AWS_USER_POOL_WEB_CLIENT_ID=myclientid
VITE_API_URL=https://api.example.com
VITE_AWS_REGION=us-east-1

GitHub Actions工作流配置

- name: Build
  run: npm run build
  env:
    VITE_API_URL: ${{ secrets.VITE_API_URL }}
    VITE_AWS_REGION: ${{ secrets.VITE_AWS_REGION }}
    VITE_AWS_USER_POOL_ID: ${{ secrets.VITE_AWS_USER_POOL_ID }}
    VITE_AWS_USER_POOL_WEB_CLIENT_ID: ${{ secrets.VITE_AWS_USER_POOL_WEB_CLIENT_ID }}

咨询问题

  1. 如何正确配置Vite,无需在vite.config.ts中硬编码敏感环境变量值?
  2. 使用import.meta.env在Vite中是否存在已知问题,尤其是结合AWS Cognito时?

解决方案

1. 移除vite.config.ts中冗余的define配置

Vite默认会自动处理以VITE_开头的环境变量,无需手动在define中声明import.meta.env变量——手动声明会覆盖Vite的默认注入逻辑,导致.env文件或CI/CD传入的变量无法生效。

修改后的vite.config.ts:

import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import path from "path";

export default defineConfig(({ mode }) => {
  loadEnv(mode, process.cwd(), ''); // 仅加载环境变量,无需手动赋值

  return {
    plugins: [react(), tailwindcss()],
    base: "/",
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./src"),
        './runtimeConfig': './runtimeConfig.browser',
      },
    },
    define: {
      'process.env': {} // 仅保留这一行(兼容依赖中使用process.env的情况)
    }
  };
});

2. 确保环境变量文件的正确性

  • 环境变量文件必须放在项目根目录,不能嵌套在子文件夹中
  • 开发环境使用.env.development,生产环境使用.env.production,默认.env会被所有环境加载(优先级低于环境特定文件)
  • 变量名必须严格以VITE_开头,否则Vite不会自动注入

3. 代码中添加环境变量缺失的守卫逻辑

在初始化Cognito UserPool前,先检查环境变量是否存在,提前抛出明确错误,避免后续初始化失败:

import { 
  CognitoUserPool, 
  CognitoUser, 
  AuthenticationDetails,
  CognitoUserSession,
  CognitoUserAttribute
} from 'amazon-cognito-identity-js';

// 先验证环境变量是否存在
const userPoolId = import.meta.env.VITE_AWS_USER_POOL_ID;
const clientId = import.meta.env.VITE_AWS_USER_POOL_WEB_CLIENT_ID;

if (!userPoolId || !clientId) {
  throw new Error("AWS Cognito配置缺失:请确保VITE_AWS_USER_POOL_ID和VITE_AWS_USER_POOL_WEB_CLIENT_ID已正确设置");
}

const poolData = {
  UserPoolId: userPoolId,
  ClientId: clientId
};

const userPool = new CognitoUserPool(poolData);

// 后续认证函数保持不变

4. CI/CD环境验证

GitHub Actions中的配置已经正确传递了环境变量,构建时Vite会自动将这些变量注入到代码中,无需额外处理。


关于import.meta.env与AWS Cognito的问题

  • Vite的import.meta.env本身与AWS Cognito没有兼容性问题,核心是确保环境变量在构建阶段被正确注入(Vite会静态替换这些变量,运行时无法动态修改)。
  • 注意:AWS Cognito的UserPoolId和ClientId属于客户端可公开的配置(不是敏感密钥),可以安全地注入到前端代码中,无需担心泄露风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:05:02