237 votes

Activation de CORS dans les fonctions Cloud pour Firebase

Je suis en train d'apprendre à utiliser les nouvelles fonctions Cloud pour Firebase et le problème que je rencontre est que je ne peux pas accéder à la fonction que j'ai écrite par le biais d'une requête AJAX. Je reçois l'erreur "No 'Access-Control-Allow-Origin'". Voici un exemple de la fonction que j'ai écrite :

exports.test = functions.https.onRequest((request, response) => {
  response.status(500).send({test: 'Testing functions'});
})

La fonction se trouve dans cette url : https://us-central1-fba-shipper-140ae.cloudfunctions.net/test

La documentation de Firebase suggère d'ajouter un middleware CORS à l'intérieur de la fonction, j'ai essayé mais cela ne fonctionne pas pour moi : https://firebase.google.com/docs/functions/http-events

C'est comme ça que j'ai fait :

var cors = require('cors');    

exports.test = functions.https.onRequest((request, response) => {
   cors(request, response, () => {
     response.status(500).send({test: 'Testing functions'});
   })
})

Qu'est-ce que je fais de mal ? J'apprécierais toute aide à ce sujet.

UPDATE :

Doug Stevenson La réponse de l'auteur a été utile. L'ajout de ({origin : true}) a réglé le problème, j'ai également dû modifier response.status(500) a response.status(200) ce que j'ai complètement manqué au début.

0 votes

Vous trouverez également un exemple dans la documentation ici

0 votes

J'ai quelques fonctions qui fonctionnent avec la solution fournie mais j'essaie maintenant une nouvelle fonction qui ajoute essentiellement des graphiques ouverts en haut de mon index.html et renvoie l'index.html mis à jour et je n'arrive pas à la faire fonctionner :( je continue à obtenir l'erreur ACCESS-CONTROL---.

2 votes

Envelopper la requête entrante dans cors() comme ci-dessus est la seule chose qui a fonctionné pour moi.

232voto

Doug Stevenson Points 6978

Il y a deux exemples de fonctions fournis par l'équipe de Firebase qui démontrent l'utilisation de CORS :

Le deuxième exemple utilise une méthode de travail avec les cors différente de celle que vous utilisez actuellement.

Pensez à importer comme ceci, comme indiqué dans les exemples :

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

Et la forme générale de votre fonction sera la suivante :

exports.fn = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        // your function body here - use the provided req and res from cors
    })
});

5 votes

Il semble que c'est ici qu'est définie la liste blanche des domaines dont l'accès est autorisé ? Et le paramètre origin: true permet à tout domaine d'y accéder ? ( npmjs.com/package/cors ) @Doug Stevenson Pensez-vous que firebase pourrait rédiger une doc sur les bases nécessaires aux fonctions https client/serveur ? Le repo d'échantillons est bon, mais nous avons manqué cette partie supplémentaire de l'exigence.

21 votes

À tous ceux qui souhaitent ajouter le support CORS à leurs backends : assurez-vous de bien comprendre les conséquences et de savoir comment le configurer correctement. "origin : true" est cool pour les tests mais cela va à l'encontre du but recherché :)

0 votes

@dSebastien, pouvez-vous donner un exemple de cors avec une origine spécifique qui, je suppose que c'est ce que vous voulez dire, devrait être utilisé ? J'ai du mal à le faire fonctionner

131voto

deanwilliammills Points 379

Vous pouvez définir le CORS dans la fonction "cloud" comme suit

response.set('Access-Control-Allow-Origin', '*');

Il n'est pas nécessaire d'importer le cors paquet

2 votes

Cela fonctionne parfaitement dans mon cas, une fonction cloud qui fait un appel XHR à l'API Mailchimp.

1 votes

Les fonctions de google cloud n'autorisent pas l'origine joker : cloud.google.fr/functions/docs/écriture/

4 votes

@CoreyCole I pensez à c'est seulement si vous avez besoin d'ajouter les Authorization en-tête. Ce qui précède semble fonctionner correctement.

74voto

Yayo Arellano Points 1395

Pour ceux qui essaient de faire cela en Typescript, voici le code :

import * as cors from 'cors';
const corsHandler = cors({origin: true});

export const exampleFunction= functions.https.onRequest(async (request, response) => {
       corsHandler(request, response, () => {});
       //Your code here
});

5 votes

Cette solution vous fera perdre la journalisation des fonctions en nuage (très mauvais) et la fonctionnalité async / await correcte, vous risquez de voir le contenu de la fonction se terminer prématurément dans le callback lors d'appels longs.

2 votes

Les fonctions de google cloud n'autorisent pas l'origine joker : cloud.google.fr/functions/docs/écriture/

5 votes

@YayoArellano, merci. Votre réponse m'a aidé, cependant j'ai fait un léger changement : corsHandler(request, response, () => { YOUR CODE HERE });

50voto

Pablo Urquiza Points 131

Une information supplémentaire, juste pour ceux qui chercheront cette information sur Google après un certain temps : Si vous utilisez l'hébergement firebase, vous pouvez également configurer des réécritures, de sorte que, par exemple, une url comme (firebase_hosting_host)/api/myfunction redirige vers la fonction (firebase_cloudfunctions_host)/doStuff. De cette façon, puisque la redirection est transparente et côté serveur, vous n'avez pas à vous occuper des cors.

Vous pouvez configurer cela avec une section de réécriture dans firebase.json :

"rewrites": [
        { "source": "/api/myFunction", "function": "doStuff" }
]

3 votes

À mon avis, c'est la meilleure solution, car elle résout le problème réel sans ajouter de problèmes de sécurité supplémentaires. De cette façon, les fonctions de cloud sont servies à partir du même domaine que le reste et vous n'avez même pas besoin de cors.

6 votes

Il s'agit d'une excellente fonctionnalité, mais elle ne fonctionne actuellement que si les fonctions vivent dans la région par défaut (us-central1). J'ai voulu déployer mes fonctions vers europe-west1 pour des raisons de latence et j'ai rencontré ce problème : github.com/firebase/firebase-tools/issues/842

1 votes

La redirection fonctionne bien et rend l'URL plus propre, mais je n'ai pas trouvé comment passer des paramètres GET. La fonction (après réécriture) semble être appelée sans paramètres.

23voto

Jaap Weijland Points 696

J'ai un petit complément à la réponse d'@Andreys à sa propre question.

Il semble que vous n'ayez pas besoin d'appeler le callback dans la section cors(req, res, cb) de sorte que vous pouvez simplement appeler le module cors au début de votre fonction, sans intégrer tout votre code dans la fonction de rappel. C'est beaucoup plus rapide si vous voulez implémenter les cors par la suite.

exports.exampleFunction = functions.https.onRequest((request, response) => {
    cors(request, response, () => {});
    return response.send("Hello from Firebase!");
});

N'oubliez pas de mettre des cors init comme mentionné dans le post d'ouverture :

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

Mise à jour : Toute fonction de réponse qui prend du temps risque une erreur CORS avec cette implémentation car elle n'a pas l'async/await approprié. Ne l'utilisez pas en dehors des points de terminaison de prototypage rapide qui renvoient des données statiques.

2 votes

Cela a fonctionné alors que d'autres réponses de l'OS avec le réglage manuel des en-têtes n'ont pas fonctionné.

0 votes

Cela fonctionne mais peut provoquer une erreur TSlint si vous l'avez activé et que vous ne pouvez pas déployer sur firebase. Mettez la réponse à l'intérieur de la fermeture cors pour le surmonter cors(request, response, () => { return response.send("Hello from Firebase!"); });

2 votes

2 erreurs ici les gars. La première. Tout ce qui suit la fonction cors sera exécuté deux fois (puisque la première demande est le contrôle en amont). Ce n'est pas bon. Deuxièmement, @SpiralOut votre solution vous fera perdre la journalisation sur les fonctions cloud (très mauvais) et la fonctionnalité async / await appropriée, vous risquez que le contenu de la fonction soit prématurément terminé à l'intérieur du callback.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X