Маркер безопасности недействителен при вызове API с помощью AWS Amplify & Cognito - PullRequest
1 голос
/ 10 апреля 2019

Я пытаюсь установить AWS Amplify в существующий угловой проект. Я использую Cognito User Pool с Cognito Federated Identity. Я могу войти в систему, но когда я попытался вызвать мой API, я получил сообщение {"message":"The security token included in the request is invalid."} с кодом статуса 403 Forbidden.

Мой API развернут на API Gateway с использованием Serverless Framework с этой настройкой У меня включены 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

Я надеюсь, что кто-нибудь сможет мне помочь с этим. Спасибо.

1 Ответ

0 голосов
/ 12 апреля 2019

Я наконец-то нашел решение этой проблемы после нескольких дней поиска.

Первым шагом было установить уровень логарифма усиления по крайней мере на 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.

Решение состояло в том, чтобы поместить полифилл в window не в polyfill.ts, а в index.html, например:

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

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

Наконец-то это работает.

...