web-dev-qa-db-fra.com

Le point de terminaison AWS API Gateway donne une erreur CORS lorsque POST à partir d'un site statique sur S3

J'ai créé un point de terminaison API avec Serverless (serverless.com) que j'expose via API Gateway. J'obtiens l'erreur suivante même si j'ai activé CORS à partir du

XMLHttpRequest ne peut pas se charger https://xxxxxxxxx.execute-api.us-west-2.amazonaws.com/development/signup . Aucun en-tête "Access-Control-Allow-Origin" n'est présent sur la ressource demandée. L'origine ' http://yyyyyyyyy.com.s3-website-us-east-1.amazonaws.com ' n'est donc pas autorisée à y accéder.

AWS API Gateway settings for the endpoint

Je ne reçois aucune erreur lorsque j'utilise Postman pour faire des demandes, bien que j'aie défini l'en-tête Origin ou non. Comment puis-je résoudre ce problème?

16

Nous avons un bogue en ce moment où les demandes échouées à API Gateway n'incluront pas les en-têtes CORS appropriés, ce qui masque l'erreur réelle sur la demande.

Je voudrais ajouter à ce que Ken a dit et m'assurer que vous avez soigneusement testé l'API et les ressources dans la console et également sur la version déployée à l'aide de Postman ou d'un autre client qui n'est pas un navigateur. Je pense qu'il y a un problème avec l'API elle-même et que votre configuration CORS est correcte.

13
Jack Kohn - AWS

Comme l'a souligné Jack Kohn, la console AWS n'ajoute pas les en-têtes CORS sur la réponse non 200 et, apparemment, ne vous permet pas d'ajouter d'en-tête personnalisé.

J'ai pu activer les en-têtes CORS en cas d'échec de la demande en exportant vers Swagger et en modifiant manuellement le fichier (juste copié la réponse 200) et en le réimportant.

Les réponses devraient ressembler à ceci:

  responses:
    200:
      description: "200 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
    401:
      description: "401 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
  x-Amazon-apigateway-integration:
    responses:
      default:
        statusCode: "200"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"
      Authentication Failed.*:
        statusCode: "401"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"

J'espère que cela t'aides.

6
Tiago Lopo

Je commencerais le dépannage en inspectant votre API dans la console AWS pour m'assurer que sans serveur enregistré tout comme vous l'attendez.

  1. Chargez la console AWS et accédez au service API Gateway.
  2. Cliquez sur l'API pour l'ouvrir.
  3. Trouvez votre ressource/inscription
  4. Assurez-vous de voir la méthode OPTIONS sous/inscription
  5. Cliquez sur chaque ressource, y compris les options et vérifiez les points suivants:

    une. Cliquez sur Réponse d'intégration, cliquez sur la flèche dans la première ligne du tableau pour 200 pour l'ouvrir.

    b. Cliquez sur la flèche pour ouvrir les mappages d'en-tête

    c. Assurez-vous que Access-Control-Allow-Origin est mappé sur '*'

Si vous trouvez cet en-tête manquant dans l'une des méthodes, une solution rapide consiste à cliquer de nouveau sur la ressource/signup et à cliquer sur le bouton Activer CORS. AWS construira pour vous des OPTIONS et des mappages d'en-tête sur toutes les méthodes. Bien sûr, vous devez toujours comprendre pourquoi le serveur sans serveur n'a pas configuré les choses pour vous, mais cela vous permettra au moins de démarrer.

Une autre note sur le bouton Activer CORS, si vous ajoutez une autre méthode plus tard, vous devrez cliquer à nouveau pour réexécuter l'outil pour configurer votre nouvelle méthode avec CORS.

3
kennbrodhagen

J'ai ce problème ... J'active CORS, le test fonctionne car il envoie les en-têtes, mais quand je l'appelle depuis mon application, il échoue et aucun en-tête n'a été trouvé sur la réponse.

c'est parce qu'après avoir défini CORS, vous devez DEPLOYER l'API. J'ai déployé l'API et tout fonctionne très bien.

2
Cristian Sepulveda

Je rencontrais des difficultés avec le même problème lorsque "POST" sur API Gateway. Mais j'ai trouvé la solution au problème.

Après avoir activé CORS pour la ressource de méthode et après avoir ajouté les en-têtes nécessaires, par exemple 'Access-Control-Allow-Origin' = '*' wildcard, et il échoue toujours.

Allez aux OPTIONS de la ressource que vous invoquez, 'GET', 'POST', etc .. cliquez sur le volet "Method Request" de cette ressource, définissez API Key = FALSE, ne définissez PAS la clé API sur true. Cela entraînera l'erreur CORS.

Raison, OPTIONS n'est techniquement pas une méthode, c'est une fonction de navigateur pour exécuter la demande de contrôle en amont, donc pendant le contrôle en amont, le navigateur ne sait pas quelle clé API envoyer, il ne saura que lorsque la réponse sera retournée au navigateur d'Access -Control-Allow-Origin '=' * 'puis il recherchera le code de la requête HTTP vers setHeaders de X-Api-Key = une valeur.

Remarque: la méthode invoke elle-même, 'POST', etc. peut avoir la clé API = True, ce qui est parfaitement correct.

J'espère que cela aidera ceux qui se débattent comme je l'ai fait pendant un certain temps :)

2
Michael Tung

Vous devez activer CORS pour toutes les méthodes. Signifie, vous devez ajouter ci-dessous trois en-têtes pour toutes vos méthodes

            "headers": {
            "Access-Control-Allow-Origin": {
                "type": "string"
            },
            "Access-Control-Allow-Methods": {
                "type": "string"
            },
            "Access-Control-Allow-Headers": {
                "type": "string"
            }
        }

Il est fastidieux d'ajouter ces en-têtes à toutes vos méthodes en JSON.

Création d'un utilitaire dans Java qui ajoute automatiquement ces en-têtes à Swagger JSON. Vous pouvez l'exécuter avant de l'importer dans API Gateway et importer le JSON de sortie qui a CORS activé dans toutes les méthodes

https://github.com/anandlalvb/SwaggerToAPIGateway

J'espère que cet utilitaire peut aider quiconque le recherche à le faire facilement.

0
binary

La réponse devrait avoir, si vous utilisez AWS lambda, définissez les en-têtes de réponse comme suit. La configuration sur API Gateway uniquement ne fonctionnera pas

headers: {
            'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*',
        },
0
PRP

J'utilise AWS sdk pour les téléchargements, après avoir passé un peu de temps à chercher en ligne, je suis tombé sur ce fil. grâce à @lsimoneau 45581857 il s'avère que la même chose se passait exactement. J'ai simplement pointé ma demande URL vers la région sur mon seau en attachant la propriété de la région et cela a fonctionné.

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });
0
davyCode

J'ai eu à peu près le même problème, car j'ai posté dans une autre question, j'ai dû ajouter les en-têtes suivants à ma réponse:

headers: {
            'Access-Control-Allow-Origin' : '*',
            'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Credentials' : true,
            'Content-Type': 'application/json'
        }

Et, selon cette documentation:

http://docs.aws.Amazon.com/apigateway/latest/developerguide/how-to-cors.html

Lorsque vous utilisez un proxy pour les fonctions lambda dans la configuration d'API Gateway, les méthodes post ou get n'ont aucun en-tête ajouté, seule la méthode options le fait. Vous devez le faire manuellement dans la réponse (serveur ou réponse lambda).

En plus de cela, je devais désactiver l'option 'API Key Required' dans ma méthode de publication de passerelle API, comme quelqu'un l'a déjà dit.