如何在 JavaScript SDK v3 中的 cognito 中实现开发人员验证的身份 - 在客户端中获取 403 InvalidSignatureException 响应

问题描述 投票:0回答:1

我正在 Angular 应用程序中实现开发人员验证的身份,该应用程序使用官方文档中的“增强工作流程”。我遵循官方指南来实现这一点,并在服务器端使用 GetOpenIdTokenForDeveloperIdentityRequest() 为我的最终用户请求令牌,并将其返回到我的 Angular Web 客户端,以便 Web 客户端可以获取其临时令牌来自 Cognito 的凭证。不幸的是,该指南没有更新以说明如何在 SDK 版本 3 中实现此目的(大多数在线问题和解决方案也引用旧版本的 SDK),但我正在设法从 Cognito 获取一组凭据。 (在下面的代码中,我创建了一个 console.log 来写出我收到的凭据。到目前为止已经很完美了。)

问题是我不知道如何正确构建服务客户端来使用这些凭据。以下是我的尝试。我正在构建一个服务客户端(在本例中为 LocationClient)并通过该客户端上的命令发送(GetDevicePositionCommand)。但是,这会引发错误,如果我检查进行的网络调用,我会发现进行此调用时的网络响应是 X-Amzn-Errortype“InvalidSignatureException”的 403 错误。错误信息是:

"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method." 

The Canonical String for this request should have been....

我是否正确使用从 Cognito 返回的临时凭证来构建服务客户端 (LocationClient)?关于如何解决这个问题有什么想法吗? (我已经查阅了这个故障排除指南,但我没有找到任何有用的东西。)下面是我的 Angular Web 应用程序的客户端代码。

const cognitoIdentity = new CognitoIdentityClient({
    credentials : fromCognitoIdentity({
        identityId: 'IDENTITY_ID_RETURNED_FROM_MY_DEVELOPER_PROVIDER', //IdentityId returned from calling GetOpenIdTokenForDeveloperIdentityRequest() on my server-side
        logins: {
        'cognito-identity.amazonaws.com': 'TOKEN_RETURNED_FROM_MY_DEVELOPER_PROVIDER' //Token returned from calling GetOpenIdTokenForDeveloperIdentityRequest() on my server-side
        },
        clientConfig: {region: "eu-west-1"},
    }),
});

const credentials = await cognitoIdentity.config.credentials()
console.log(credentials) //There's output! So this part works.
  // {
  //    identityId: 'eu-west-1:XXXX',
  //    accessKeyId: 'ALA...',
  //    secretAccessKey: '/XXXXxxxXXXXxxXXXxXXXXX',
  //    sessionToken: 'IQoJb3JpZ2luX2VjEJj//////////...', // sessionToken cut for brevity
  //    expiration: 2024-02-13T08:58:10.000Z
  //  }

const trackingClient = new LocationClient({
    region: 'eu-west-1',
    credentials: credentials,
});

const input = {
    TrackerName: "xxxxx",
    DeviceId: "xxxxxxx",
  };
const posCommand = new GetDevicePositionCommand(input);

try
{
  const response = await trackingClient.send(posCommand); //This line throws an error
}
catch(error){
    console.log('error') //Error caught
};
amazon-web-services amazon-cognito amazon-cognito-identity-js amazon-javascript-sdk
1个回答
0
投票

我设法解决了这个问题。

在设置一个小代码片段向某人说明问题时,我发现当我创建“普通”NodeJS 或“普通”Angular 应用程序时,一切都与我的代码和 AWS 库完全一样地正常工作。

深入研究我们的特定应用程序所构建的框架(ASP.NET Zero),我发现它重写了 .toISOString() 和 .toString() 的标准 JavaScript Date 方法。 AWS SDK显然并不期望这样的自定义格式,但结果是它计算签名的日期格式与AWS期望的不匹配。 (SignatureV4 期望 x-amz-date 标头采用 ISO 8601“基本”格式,而我们使用的框架中的重写方法将日期格式重写为 ISO 8601“扩展”格式。) x-amz -date 标头必须采用 YYYYMMDDTHHMMSSZ 形式(例如 20220830T123600Z),但覆盖代码导致所有日期转换类似于 20240226T093306.631+0000。

AWS SDK 库以及我们在代码中使用它的方式都是 100% 正确的。问题是因为 SDK 所依赖的(标准)方法已被 ASP.NET 零框架(我们的应用程序基于该框架构建)覆盖。

我通过删除覆盖自定义解决了这个问题,以便日期函数可以正常运行! (因为重写这样的标准函数显然会影响人们可能在其应用程序中使用的其他库!ASP.NET Zero 在框架中重写它是荒谬的!)

© www.soinside.com 2019 - 2024. All rights reserved.