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

Angular调用AWS Rekognition返回InvalidSignatureException问题求助

Angular5 + AWS SDK JS: InvalidSignatureException with Rekognition Promises but Callbacks Work

Let me break down what's happening here and how to fix it properly:

The Problem

You're hitting an InvalidSignatureException when using .promise() with Rekognition's detectLabels, even though the callback function works perfectly. This isn't an issue with your credentials, region setup, or service permissions—it's a quirk in how the AWS SDK handles request processing.

When you pass a callback to detectLabels and call .promise() on the same request object, the SDK fires two separate API requests. The first request (handled by the callback) signs correctly and succeeds, but the second request (for the promise) ends up with an invalid signature. This happens because the signature generation logic gets confused when processing the same request twice, especially with signatureCache: false enabled.

The Fix: Pick One Pattern, Not Both

You need to use either callback/event listener mode or Promise mode—don't mix them on the same request. Here are the clean, permanent solutions:

Solution 1: Pure Promise Pattern (Recommended for Modern Angular)

Drop the callback entirely and use the Promise API directly, which fits seamlessly with Angular's async workflows:

const rekognition = new Rekognition({
  accessKeyId: this.accessKeyId,
  secretAccessKey: this.secretAccessKey,
  region: this.region,
  signatureCache: false,
  signatureVersion: 'v4'
});

const params = {
  Image: {
    S3Object: {
      Bucket: this.bucket,
      Name: this.fileName
    }
  }
};

// No callback—just use .promise()
rekognition.detectLabels(params).promise()
  .then(data => {
    console.log(JSON.stringify(data, null, '\t'));
    this.labels = data.Labels;
  })
  .catch(err => {
    console.error('Rekognition error:', err, err.stack);
  });

For even cleaner code, use async/await in your Angular methods:

async fetchImageLabels() {
  try {
    const rekognition = new Rekognition({ /* your config */ });
    const params = { /* your image params */ };
    const data = await rekognition.detectLabels(params).promise();
    console.log('Labels retrieved:', data);
    this.labels = data.Labels;
  } catch (err) {
    console.error('Failed to fetch labels:', err);
  }
}

Solution 2: Stick with Event Listeners (If You Prefer)

If you want to keep using the event-based approach from your temporary fix, just avoid calling .promise() on the request object. Your workaround works because it only triggers one request, which signs correctly—no conflicting duplicate requests mean no signature mismatch.

Critical Security Warning

Before wrapping up—never hardcode AWS access keys in client-side Angular code! Exposing your accessKeyId and secretAccessKey in frontend code is a huge security risk; anyone can inspect your app's bundle and steal them to misuse your AWS resources.

Instead:

  • Use an AWS backend proxy (like API Gateway + Lambda) to handle Rekognition requests
  • Or use AWS Cognito to issue temporary, scoped credentials to your users

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:48:10