web-dev-qa-db-fra.com

API Gateway CORS: pas d'en-tête 'Access-Control-Allow-Origin'

Bien que CORS ait été configuré via API Gateway et que l'en-tête Access-Control-Allow-Origin soit défini, le message d'erreur suivant s'affiche quand je tente d'appeler l'API depuis AJAX dans Chrome:

XMLHttpRequest ne peut pas charger http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY . Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée. Origin 'null' n'est donc pas autorisé à accéder. La réponse avait le code d'état HTTP 403.

J'ai essayé d'obtenir l'URL via Postman et il montre que l'en-tête ci-dessus est passé avec succès:

 Passed headers

Et de la réponse OPTIONS:

 Response headers

Comment puis-je appeler mon API à partir du navigateur sans revenir à JSON-P?

42
makinbacon

J'ai le même problème. J'ai utilisé 10 heures pour la découverte. 

https://serverless.com/framework/docs/providers/aws/events/apigateway/

// handler.js

'use strict';

module.exports.hello = function(event, context, callback) {

const response = {
  statusCode: 200,
  headers: {
    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS 
  },
  body: JSON.stringify({ "message": "Hello World!" })
};

callback(null, response);
};
61
riseres

Si quelqu'un d'autre se heurte encore à cela, j'ai pu retrouver la cause première de mon application. 

Si vous exécutez API-Gateway avec des autorisateurs personnalisés, API-Gateway renverra un message 401 ou 403 avant qu'il ne frappe réellement votre serveur. Par défaut, API-Gateway N'EST PAS configuré pour CORS lors du renvoi 4xx à partir d'un autoriseur personnalisé.

En outre, si vous obtenez un code d'état de 0 ou 1 à partir d'une demande exécutée via API Gateway, c'est probablement votre problème.

Pour corriger - dans la configuration de la passerelle API - allez à "Réponses de la passerelle", développez "4XX par défaut" et ajoutez-y un en-tête de configuration CORS. c'est à dire.

Access-Control-Allow-Origin: '*'

Assurez-vous de redéployer votre passerelle - et le tour est joué!

37
Gabriel Doty

Mon échantillon a bien fonctionné: j'ai seulement inséré 'Accès-Contrôle-Autoriser-Origine': '*', dans en-têtes: {} dans la fonction nodejs Lambda générée. J'ai apporté no modifications à la couche d'API générée par Lambda.

Voici mon NodeJS:

'use strict';
const doc = require('dynamodb-doc');
const dynamo = new doc.DynamoDB();
exports.handler = ( event, context, callback ) => {
    const done = ( err, res ) => callback( null, {
        statusCode: err ? '400' : '200',
        body: err ? err.message : JSON.stringify(res),
        headers:{ 'Access-Control-Allow-Origin' : '*' },
    });
    switch( event.httpMethod ) {
        ...
    }
};

Voici mon appel AJAX

$.ajax({
    url: 'https://x.execute-api.x-x-x.amazonaws.com/prod/fnXx?TableName=x',
    type: 'GET',
    beforeSend: function(){ $( '#loader' ).show();},
    success: function( res ) { alert( JSON.stringify(res) ); },
    error:function(e){ alert('Lambda returned error\n\n' + e.responseText); },
    complete:function(){ $('#loader').hide(); }
});
9
MannyC

1) Je devais faire la même chose que @riseres et quelques autres modifications. Voici les en-têtes de 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'
        }

2) 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 pas d'en-têtes ajoutés, mais uniquement les options. Vous devez le faire manuellement dans la réponse (serveur ou réponse lambda).

3) Et

À côté de cela, je devais désactiver l'option 'API Key Required' dans la méthode de publication de ma passerelle API.

Si vous avez tout essayé en vain, vous vous retrouverez comme moi. Il s'avère que les instructions de configuration CORS existantes d'Amazon fonctionnent parfaitement ... assurez-vous simplement que vous n'oubliez pas de redéployer! L’assistant d’édition CORS, même avec toutes ses petites coches vertes, ne met pas à jour en direct votre API. Peut-être évident, mais ça m'a stoppé pendant une demi-journée.

 enter image description here

2
lase

Dans mon cas, j’écrivais simplement l’URL de la requête de récupération erronée. Sur serverless.yml, vous définissez cors sur true:

register-downloadable-client:
    handler: fetch-downloadable-client-data/register.register
    events:
      - http:
          path: register-downloadable-client
          method: post
          integration: lambda
          cors: true
          stage: ${self:custom.stage}

et ensuite, sur le gestionnaire lambda, vous envoyez les en-têtes, mais si vous effectuez la requête d'extraction de manière erronée sur le serveur, vous n'obtiendrez pas cet en-tête dans la réponse et vous obtiendrez cette erreur. Alors, vérifiez votre URL de demande sur le front.

0
Ericson Willians

Le mien a fonctionné après avoir réalisé que l’autorisateur lambda échouait et pour une raison inconnue qui était traduite en une erreur CORS. Un correctif simple à mon autorisateur (et à certains tests d’autoriseurs que j’aurais dû ajouter en premier lieu) et cela a fonctionné. Pour moi, l'action "Activer CORS" de la passerelle API était requise. Cela a ajouté tous les en-têtes et autres paramètres dont j'avais besoin dans mon API.

0
RodP

Dans mon cas, étant donné que j'utilisais AWS_IAM en tant que méthode d'autorisation, je devais accorder des autorisations à mon rôle IAM pour accéder au noeud final.

0
CamHart

Je suis en cours d'exécution aws-serverless-express, et dans mon cas, nécessaire pour éditer simple-proxy-api.yaml

Avant que CORS ne soit configuré en https://example.com, je viens de permuter le nom de mon site et de le redéployer via npm run setup, et le fichier lambda/pile existant a été mis à jour.

#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
0
James L.

Une autre cause fondamentale de ce problème pourrait être une différence entre HTTP/1.1 et HTTP/2.

Symptôme: Certains utilisateurs, mais pas tous, ont signalé une erreur CORS lors de l'utilisation de notre logiciel.

Problème: L'en-tête Access-Control-Allow-Origin était manquant parfois .

Contexte: Nous avions un Lambda en place, dédié à la gestion de la demande OPTIONS et à la réponse avec les en-têtes CORS correspondants, comme Access-Control-Allow-Origin correspondant à une liste blanche Origin.

Solution: La passerelle API semble transformer tous les en-têtes en minuscules pour les appels HTTP/2, mais conserve la capitalisation pour HTTP/1.1. Cela a entraîné l'échec de l'accès à event.headers.Origin.

Vérifiez si vous rencontrez ce problème aussi:

En supposant que votre API se trouve à https://api.example.com et votre interface frontale à https://www.example.com. En utilisant CURL, faites une requête en utilisant HTTP/2:

curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com

Le résultat de la réponse doit inclure l’en-tête:

< Access-Control-Allow-Origin: https://www.example.com

Répétez la même étape avec HTTP/1.1 (ou avec un en-tête Origin minuscule):

curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com

Si l'en-tête Access-Control-Allow-Origin est manquant, vous pouvez vérifier la sensibilité à la casse lors de la lecture de l'en-tête Origin.

0
Michael Seibt