Amplify: заголовок CORS «Access-Control-Allow-Origin» отсутствует, хотя CORS включен в заголовках API Gateway и Lambda.

Я использую Amplify, и мой API-шлюз проксирует Lambda. Я включил CORS на моем /{proxy+} и развернул API. В моей лямбда-функции я устанавливаю соответствующий заголовок в своей тривиальной функции:

import json


def handler(event, context):
    print("received event:")
    print(event)
    return {
        "statusCode": 200,
        "headers": {
            "Access-Control-Allow-Credentials": True,
            "Access-Control-Allow-Headers": "Content-Type",
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET",
            "Access-Control-Allow-Origin": "*",
        },
        "body": json.dumps(event),
    }

Эта функция Lambda находится за ресурсом шлюза API, который аутентифицируется через Cognito.

Когда я вызываю свой API с помощью Amplify:

let myInit = {
          headers: {
            Authorization: `Bearer ${(await Auth.currentSession())
              .getIdToken()
              .getJwtToken()}`
          }
        }; 

API.get("adminapi", "/admin", myInit) ...

Я получаю ужасный заголовок CORS 'Access-Control-Allow-Origin', отсутствующий в моем GET запросе:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/admin. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Я вижу это возвращено в OPTIONS запросе:

введите описание изображения здесь

Я даже протестировал в Postman, чтобы убедиться, что заголовки возвращаются:

введите описание изображения здесь

Что я здесь делаю не так? Не похоже, что вызов проходит через API-шлюз. Интересно, связано ли это с аутентификацией. Когда я тестирую почтальон с использованием своих учетных данных IAM, он работает нормально, но в моем веб-приложении с использованием токена-носителя он не работает, как указано выше.


person Mark Richman    schedule 14.04.2020    source источник
comment
Всегда цитируйте полное сообщение об ошибке. Я подозреваю, что там написано, что в предполетном ответе отсутствует заголовок, а не запрашиваемый ресурс.   -  person Quentin    schedule 14.04.2020
comment
В запросе GET отсутствует заголовок. Запрос OPTIONS работает нормально.   -  person Mark Richman    schedule 14.04.2020
comment
Обновлен вопрос, чтобы включить более подробную информацию.   -  person Mark Richman    schedule 14.04.2020
comment
Вы когда-нибудь находили решение этой проблемы?   -  person astroanu    schedule 10.05.2020


Ответы (3)


Я предполагаю, что вы забыли обработать глагол OPTIONS, который использовался для предварительного запроса и верните туда заголовок.

Вы отправляете заголовок Authorization, которого нет в списке разрешенных заголовков для " простые "запросы, следовательно, предварительный запрос выполнен.

Кроме того, чтобы получить учетные данные, вы должны убедиться, что заголовок Access-Control-Allow-Credentials: true также установлен.

Из фрагмента кода не видно, какой тип содержимого имеет тело запроса, но если это что-то иное, кроме application/x-www-form-urlencoded, multipart/form-data или text/plain (скажем, application/json), вам также необходимо внести заголовок Content-Type в белый список, используя Access-Control-Allow-Headers: Content-Type.

person CherryDT    schedule 14.04.2020
comment
OPTIONS обрабатывается (где-то), потому что возвращает access-control-allow-origin: *. Я обновил свою функцию, чтобы включить "Access-Control-Allow-Credentials": True в заголовки ответов. Такая же ситуация. Access-Control-Allow-Headers установлен в API Gateway по умолчанию как 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'. - person Mark Richman; 14.04.2020
comment
Что произойдет, если вы поместите Fiddler между ними? Проверьте, что на самом деле выходит за черту и чем это отличается от ваших тестов. Может быть, вы получаете ошибку на вашем сервере (например, недействительную аутентификацию), которая затем не возвращает эти заголовки (потому что кажется, что вы возвращаете их только в случае успеха со статусом 200)? Возможно, ваш заголовок авторизации не отправлен, потому что ваша библиотека не передает withCredentials: true в XHR ... - person CherryDT; 14.04.2020

У меня была такая же проблема. В моем предполетном OPTIONS запросе были все правильные заголовки:

access-control-allow-headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent
access-control-allow-methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
access-control-allow-origin: *

Итак, браузер начал принимать запросы после того, как я добавил

access-control-allow-origin: *

В ответ на запросы фактического метода, который я хотел использовать (не предполетный, например: метод GET, POST и т. Д.)

person Alex Simons    schedule 06.12.2020

При использовании fetch() в js, когда я удалил Cognito Authentication из конечных точек OPTIONS шлюза API, это сработало. Chrome и Firefox не отправляют заголовки авторизации в OPTIONS. Хотя с усилителем все может быть иначе. Цитата: https://fetch.spec.whatwg.org/#http-responses ...

"For a CORS-preflight request, request’s credentials mode is always "same-origin", i.e., it excludes credentials, but for any subsequent CORS requests it might not be."
person Mark    schedule 09.03.2021