首页 > 解决方案 > 使用 AWS Amplify & Cognito 调用 API 时安全令牌无效

问题描述

我正在尝试在现有的 Angular 项目中安装 AWS Amplify。我正在使用 Cognito 用户池和 Cognito 联合身份。我可以登录,但是当我尝试调用我的 API 时,我收到了{"message":"The security token included in the request is invalid."}带有 403 Forbidden 状态码的消息。

我的 API 使用带有此设置的无服务器框架部署在 API Gateway 上。我启用了 cors 并将授权人设置为 aws_iam。

// serverless.yml
frameworkVersion: ">=1.28.0 <2.0.0"

provider:
  name: aws
  runtime: go1.x

// --- omitted

functions:
  get_devices:
    handler: bin/get_devices
    events:
      - http:
          path: devices
          method: get
          cors: true
          authorizer: aws_iam

Amplify 在文件 main.ts 中配置

// main.ts
const { userPoolId, identityPoolId, userPoolWebClientId, endpoint } = environment;
Amplify.configure({
    Auth: {
        region: 'us-east-1',
        identityPoolId,
        userPoolId,
        userPoolWebClientId
    },
    API: {
        endpoints: [
            {
                name: 'API',
                endpoint,
            },
        ]
    }
});

我使用以下代码调用我的 API

@Injectable()
export class DevicesService {
    private api: APIClass;

    constructor(private http: HttpClient,
                private httpUtils: HttpUtilsService) {
        this.api = API;
    }

    findDevices(queryParams: QueryParamsModel): Observable<QueryResultsModel> {
        const promise = this.api.get('myAPI', '/devices', {});
        return from(promise).pipe(
            map((devices) => {
                console.log(devices);
                return devices;
            })
        );
    }
}

我有以下请求标头

Host: id.execute-api.us-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:4200/dashboard/(devices)
x-amz-date: 20190410T171055Z
Authorization: AWS4-HMAC-SHA256 Credential=undefined/20190410/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=920b1f832c6dfessssss8c3a0a0783848740dde68eaec95d3b35935
Origin: http://localhost:4200

以及以下响应标头

HTTP/2.0 403 Forbidden
content-type: application/json
content-length: 68
date: Wed, 10 Apr 2019 17:10:56 GMT
x-amzn-requestid: 9ab88ba9-5bb3-11e9-8467-e798767662220e
x-amzn-errortype: UnrecognizedClientException
x-amz-apigw-id: 67768JJDGGUYZ_SQ=
x-cache: Error from cloudfront
via: 1.1 5721f7035c3fc934bd3f96dbb04ba1e5.cloudfront.net (CloudFront)
x-amz-cf-id: hFy34Mv1OJBJF47UCT3wg0APyGYl0I4tgqw-K2ZeA==
X-Firefox-Spdy: h2

我希望有人能够帮助我。谢谢你。

标签: angulartypescriptamazon-web-servicesamazon-cognitoaws-amplify

解决方案


经过几天的搜索,我终于找到了解决这个问题的方法。

第一步是将放大的日志级别设置为至少 DEBUG,这样您就可以看到发生了什么。

问题是由于以下问题,Amplify 在调用 API 时无法获取保存在本地存储中的凭据。

[DEBUG] 48:49.870 AuthClass - getting session failed TypeError: Cannot read property 'Stream' of undefined
    at Object.computeSha256 (util.js:705)
    at Request.COMPUTE_SHA256 (event_listeners.js:142)
    at Request.callListeners (sequential_executor.js:105)
    at Request.emit (sequential_executor.js:81)
    at Request.emit (request.js:683)
    at Request.transition (request.js:22)
    at AcceptorStateMachine.runTo (state_machine.js:14)
    at state_machine.js:26
    at Request.<anonymous> (request.js:38)
    at Request.<anonymous> (request.js:685)

在那种情况下,Amplify 只是调用 API 而不进行任何签名,因此403 Forbidden.

解决方案是将 polyfill 放入其中windowpolyfill.tsindex.html如下所示:

<script>
    if (global === undefined) {
        var global = window;
    }

    // If you need debug message from amplify
    window['LOG_LEVEL'] = 'DEBUG';
</script>

最后它的工作。


推荐阅读