web-dev-qa-db-fra.com

Contrôle d'accès non autorisé d'origine ne fonctionne pas avec les fonctions Google Cloud du GCF

Je me sens comme un débutant ici, mais j'essaie d'exécuter une simple demande AJAX d'un navigateur pour accéder à un fichier GCF et que Chrome rapporte:

XMLHttpRequest ne peut pas charger https://us-central1-bustling-opus-830.cloudfunctions.net/Authenticate . Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée. Origin ' https://beast.reachboarding.com.au ' n'est donc pas autorisé .

J'ai une fonction appelée Authentifier (comme indiqué ci-dessus) qui utilise un seau appelé:

bustling-opus-830.appspot.com

J'ai utilisé gsutil pour configurer CORS à l'aide du fichier JSON suivant:

[{
    "Origin": ["https://beast.localdev.com.au","*"],
    "responseHeader": ["Content-Type"],
    "method": ["GET", "HEAD", "DELETE", "OPTIONS"],
    "maxAgeSeconds": 3600
}]

Avec la commande suivante:

gsutil cors set cors.json gs://bustling-opus-830.appspot.com/

Et obtenez ensuite le résultat suivant à partir de la commande get correspondante:

gsutil cors get gs://bustling-opus-830.appspot.com/

[{"maxAgeSeconds": 3600, "method": ["GET", "HEAD", "DELETE", "OPTIONS"], "Origin": ["https://beast.localdev.com.au", "*"], "responseHeader": ["Content-Type"]}]

J'utilise l'exemple de code par défaut fourni lorsque vous créez une nouvelle fonction, comme indiqué ci-dessous:

/**
 * Responds to any HTTP request that can provide a "message" field in the body.
 *
 * @param {!Object} req Cloud Function request context.
 * @param {!Object} res Cloud Function response context.
 */
exports.helloWorld = function helloWorld(req, res) {
    // Example input: {"message": "Hello!"}
    if (req.body.message === undefined) {
        // This is an error case, as "message" is required.
        res.status(200).send('No message defined!');
    } else {
        // Everything is okay.
        console.log(req.body.message);
        res.status(200).send(req.body.message);
    }
};

Et un simple HTML avec le Javascript suivant:

$.ajax({
    url: "https://us-central1-bustling-opus-830.cloudfunctions.net/Authenticate",
    type: "POST",
    data: {
        message: 'Testing'
    },
    dataType: 'json', 
    success: function (response) {
        console.log(response);
    },
    error: function (xhr, status) {
        console.log(xhr);
    }
});

Ce qui cause l'erreur.

Dans ma console DEV, je peux voir la requête réseau passer. Voici les en-têtes de réponse HTTP que je reçois sont:

cache-control:private
content-encoding:gzip
content-length:27
content-type:text/html; charset=utf-8
date:Wed, 08 Feb 2017 03:45:50 GMT
etag:W/"7-274e639a"
function-execution-id:azc1zqfb1tq8
server:Google Frontend
status:200
vary:Accept-Encoding
x-cloud-trace-context:70e08d634a9644c32530326de0471a64;o=1
x-cloud-trace-context:70e08d634a9644c32530326de0471a64
x-powered-by:Express

Je me serais attendu à voir l'en-tête Access-Control-Allow-Origin dans les en-têtes de réponse pour indiquer qu'il autorisait *, mais je ne le vois certainement pas.

La chose folle est que quand je regarde l'élément Réseau et que je clique sur Réponse, je reçois:

Testing

Ce qui suggère que toutes choses étant égales par ailleurs, il a réellement couru!

Je m'excuse si cela a déjà été répondu, mais j'ai cherché autant de mots-clés différents et rien ne semble avoir résolu mon problème. Je pensais que de nouveaux yeux sur la question (et une expertise décente) pourraient aider.

Merci d'avance!

8
Encoder

Votre fonction Google Cloud au premier plan (HTTP) doit définir les en-têtes CORS appropriés dans les réponses aux demandes du client AJAX. Les paramètres de requête et de réponse de Fonctions HTTP ont des propriétés équivalentes aux objets ExpressJS correspondants, qui peuvent être utilisés pour définir les en-têtes CORS et répondre aux requêtes de contrôle en amont, le cas échéant.

Par exemple:

exports.Authenticate = function Authenticate (req, res) {
    //set JSON content type and CORS headers for the response
    res.header('Content-Type','application/json');
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type');

    //respond to CORS preflight requests
    if (req.method == 'OPTIONS') {
        res.status(204).send('');
    }

    //continue function ...

};

Les en-têtes et la logique ci-dessus doivent être modifiés pour refléter les besoins particuliers de votre service, mais devraient, espérons-le, vous aider à démarrer.

15
ryanmac

Vous pouvez également utiliser le package cors pour résoudre ce problème, comme recommandé par Google. En fait, ils l'utilisent également dans leurs propres exemples de codes. Cochez cette exemple . Ceci est le code - 

const cors = require('cors')({
    Origin: true,
});

//Your code here

//Use the following function instead of just res.send. return keyword is not compulsory here
return cors(req, res, () => {
    res.send();
});
2
noob

Si vous êtes toujours intéressé par une réponse, j'ai en fait écrit un article sur la façon de gérer cela avec le middleware Express: https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud- functions.html .

1
mhaligowski