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

React集成测试调用Cognito报错:Native crypto模块无法获取安全随机数

解决方案

方案1:全局注入Crypto Polyfill(适合需要真实调用Cognito接口的集成测试)

这个方案是给Node测试环境补全浏览器端的crypto全局对象,完全适配Cognito的源码判断逻辑。

  • 第一步:在测试初始化的最前置位置执行polyfill代码,比如Jest的setupFiles/setupFilesAfterEnv配置指向的文件,Vitest同理,不要在单测用例内部才执行,此时Cognito依赖已经加载完成,配置不会生效。
  • 第二步:使用如下正确的polyfill代码:
// 先引入Node原生crypto模块
import * as nodeCrypto from 'crypto';
// 兼容不同运行时的全局指向
const globalAsAny = global as any;

// 同时挂载到所有可能被Cognito识别的全局对象上
globalAsAny.crypto = nodeCrypto;
globalAsAny.window = globalAsAny.window || {};
globalAsAny.window.crypto = nodeCrypto;
globalAsAny.self = globalAsAny.self || globalAsAny;

// Node 19以下版本原生crypto没有getRandomValues方法,手动补全
if (!nodeCrypto.getRandomValues) {
  nodeCrypto.getRandomValues = (typedArray: Uint8Array | Uint16Array | Uint32Array) => {
    const randomBytes = nodeCrypto.randomBytes(typedArray.length);
    for (let i = 0; i < typedArray.length; i++) {
      typedArray[i] = randomBytes[i];
    }
    return typedArray;
  };
}

方案2:Mock Cognito依赖(适合不需要真实调用Cognito接口的测试)

如果你的测试不需要真实请求AWS Cognito服务,可以直接mock对应的方法,彻底规避环境依赖问题,以Jest为例:

jest.mock('amazon-cognito-identity-js', () => {
  return {
    CognitoUser: jest.fn().mockImplementation(() => {
      return {
        authenticateUser: jest.fn((authDetails, callbacks) => {
          // 模拟成功返回,按需调整返回值
          callbacks.onSuccess({
            getIdToken: () => ({ getJwtToken: () => 'mock-jwt-token' })
          });
        })
      };
    }),
    CognitoUserPool: jest.fn(),
    AuthenticationDetails: jest.fn()
  };
});

之前方案不生效的原因

  1. 没有提前引入Node原生的crypto模块,直接赋值时crypto本身就是undefined
  2. 挂载时机过晚,Cognito的工具函数加载时,全局crypto还没有被赋值
  3. 只挂载到了单个全局对象上,部分打包配置或者运行时环境下Cognito识别的全局指向不是你挂载的对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:12:01