it-roy-ru.com

В 401 возврате из пользовательского авторизатора шлюза API отсутствует заголовок "Access-Control-Allow-Origin"

Чтобы пользователи, не вошедшие в систему, не вызывали мою лямбда-функцию через AWS API Gateway, я использую лямбда-решение Custom Authorizer.

Если запрос авторизован (200) и я получаю ответ от вызываемой лямбды, все работает нормально, и я получаю заголовок Access-Control-Allow-Origin.

Но если запрос не авторизован, я получаю 401, у которого нет заголовка Access-Control-Allow-Origin, поэтому я не могу прочитать состояние ответа 401 и перенаправить пользователя на страницу входа.

Я полагаю, что это потому, что механизм Custom Autorization не знает, что запрос должен использовать CORS. Кто-нибудь знает, что это на самом деле проблема? Вам известно о каком-либо возможном решении?

36
hanbzu

Я рад объявить о новой функции ответов шлюза, которая позволяет настраивать ответы на ошибки для запросов, которые не вызывают интеграцию. Это позволяет гарантировать, что заголовки CORS включены даже при неудачных запросах аутентификации. 

Подробнее читайте в нашей документации , которая включает пример CORS.

14
Bob Kinney

Да, это известная ошибка в пользовательских авторизаторах API Gateway. Спасибо, что сообщили нам об этом. Команда обновит этот пост, когда мы развернем исправление. Извиняюсь за неудобства. 

12
Lorenzo de Lara

Самый простой способ решить эту проблему для всех ошибок 4XX (включая ошибки 401) - перейти к «Ответам шлюза», затем выбрать «Default 4XX», а затем добавить заголовок «Access-Control-Allow-Origin» со значением '* ».

Смотрите скриншот: 

5
Alex Robinson

Поскольку мне потребовалось некоторое время, чтобы понять, как собрать все это вместе в Cloud Formation, вот фрагмент, показывающий, как его настроить.

...
    MyApi:
      Type: "AWS::ApiGateway::MyApi"
      Properties:
        Description: My API
        Name: "my-api"
    MyApiAuthorizer:
      Type: "AWS::ApiGateway::Authorizer"
      Properties:
         Name: "my-api-authorizer"
         IdentitySource: "method.request.header.Authorization"
         ProviderARNs:
           - !GetAtt MyUserPool.Arn
         RestApiId: !Ref MyAApi
         Type: COGNITO_USER_POOLS
    MyApiGatewayResponse:
      Type: "AWS::ApiGateway::GatewayResponse"
      Properties:
        ResponseParameters:
          "gatewayresponse.header.Access-Control-Allow-Origin": "'*'"
          "gatewayresponse.header.Access-Control-Allow-Headers": "'*'"
        ResponseType: UNAUTHORIZED
        RestApiId: !Ref MyApi
        StatusCode: "401"
3
pisomojado

В дополнение к ответам выше, если вы не используете шаблон Cloudformation/SAM, вы можете сэкономить некоторые ручные шаги, используя этот скрипт на python:

import boto3
import sys

if len(sys.argv) != 3:
    print("usage: python script.py <API_ID> <STAGE>")
    exit()

client = boto3.client('apigateway')

response = client.put_gateway_response(
    restApiId=sys.argv[1],
    responseType='UNAUTHORIZED',
    statusCode='401',
    responseParameters={
        "gatewayresponse.header.Access-Control-Allow-Origin": "'*'",
        "gatewayresponse.header.Access-Control-Allow-Headers": "'*'"
    }
)
response = client.create_deployment(
    restApiId=sys.argv[1],
    stageName=sys.argv[2])
0
amsh