web-dev-qa-db-fra.com

Activation de CORS dans les fonctions de cloud pour Firebase

J'apprends actuellement à utiliser les nouvelles fonctions de cloud pour Firebase et le problème que je rencontre est que je ne peux pas accéder à la fonction que j'ai écrite via une requête AJAX. J'obtiens l'erreur "Non 'Accès-Contrôle-Autoriser-Origine". 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

Firebase docs suggère d’ajouter un middleware CORS dans la fonction. Je l’ai essayé mais cela ne fonctionne pas pour moi: https://firebase.google.com/docs/functions/http-events

Voici comment je l'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 mal? J'apprécierais n'importe quelle aide avec ceci.

METTRE À JOUR:

La réponse de Doug Stevenson a aidé. L'ajout de ({Origin: true}) a corrigé le problème. J'ai également dû remplacer response.status(500) en response.status(200), ce que j'ai complètement manqué au début.

62
Andrey Pokrovskiy

Il existe deux exemples de fonctions fournies par l’équipe Firebase qui démontrent l’utilisation de CORS:

Le deuxième exemple utilise une manière de travailler avec cors différente de celle que vous utilisez actuellement.

En outre, envisagez d'importer comme ceci, comme indiqué dans les exemples:

const cors = require('cors')({Origin: true});
82
Doug Stevenson

Vous pouvez définir la fonction CORS dans le cloud comme suit: response.set('Access-Control-Allow-Origin', '*');. Inutile d'importer le package cors.

18
deanwilliammills

Pour ceux qui essaient de le faire dans 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
});
17
Yayo Arellano

Une information supplémentaire, juste pour le plaisir de googler ceci 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 du type (firebase_hosting_Host)/api/myfunction redirect à la fonction (firebase_cloudfunctions_Host)/doStuff. De cette façon, puisque la redirection est transparente et côté serveur, vous n’avez pas à faire face aux problèmes.

Vous pouvez configurer cela avec une section rewrites dans firebase.json:

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

Je viens de publier un petit article à ce sujet:

https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html

En règle générale, vous devez utiliser Express CORS package , qui nécessite un peu de piratage pour répondre aux exigences des fonctions GCF/Firebase.

J'espère que cela pourra aider!

6
mhaligowski

Aucune solution CORS n'a fonctionné pour moi ... jusqu'à maintenant!

Je ne suis pas sûr que quelqu'un d'autre ait rencontré le même problème que moi, mais j'ai créé CORS de cinq manières différentes à partir d'exemples que j'ai trouvés et rien ne semblait fonctionner. J'ai créé un exemple minimal avec Plunker pour voir si c'était vraiment un bug, mais l'exemple a fonctionné à merveille. J'ai décidé de vérifier les journaux des fonctions firebase (disponibles dans la console firebase) pour voir si cela pouvait me dire quoi que ce soit. J'ai eu quelques erreurs dans le code de mon serveur de nœud , pas lié à CORS , que lorsque j'ai débogué m'a publié mon message d'erreur CORS . Je ne sais pas pourquoi les erreurs de code qui ne sont pas liées à CORS renvoient une réponse d'erreur CORS, mais cela m'a conduit vers le mauvais trou de lapin pendant un bon nombre d'heures ...

tl; dr - vérifie les journaux de votre fonction firebase si aucune solution CORS ne fonctionne et déboguez les erreurs que vous avez

4
tbone849

Cela pourrait être utile. J'ai créé la fonction de cloud HTTP firebase avec express (URL personnalisée)

const express = require('express');
const bodyParser = require('body-parser');
const cors = require("cors");
const app = express();
const main = express();

app.post('/endpoint', (req, res) => {
    // code here
})

app.use(cors({ Origin: true }));
main.use(cors({ Origin: true }));
main.use('/api/v1', app);
main.use(bodyParser.json());
main.use(bodyParser.urlencoded({ extended: false }));

module.exports.functionName = functions.https.onRequest(main);

S'il vous plaît assurez-vous que vous avez ajouté des sections de réécriture

"rewrites": [
      {
        "source": "/api/v1/**",
        "function": "functionName"
      }
]
2
Sandy

Seulement cette façon fonctionne pour moi comme j'ai l'autorisation dans ma demande:

exports.hello = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', '*');
response.set('Access-Control-Allow-Credentials', 'true'); // vital
if (request.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    response.set('Access-Control-Allow-Methods', 'GET');
    response.set('Access-Control-Allow-Headers', 'Content-Type');
    response.set('Access-Control-Max-Age', '3600');
    response.status(204).send('');
} else {
    const params = request.body;
    const html = 'some html';
    response.send(html)
} )};
2
Gleb Dolzikov

Pour ce que cela vaut, j’avais le même problème lorsque je passais app en onRequest. J'ai réalisé que le problème était une barre oblique de fin sur l'URL de la demande pour la fonction firebase. Express recherchait '/' mais je n'avais pas la barre oblique finale sur la fonction [project-id].cloudfunctions.net/[function-name]. L'erreur CORS était un faux négatif. Lorsque j'ai ajouté la barre oblique finale, j'ai obtenu la réponse à laquelle je m'attendais. 

1
shadyhill

S'il y a des gens comme moi: Si vous souhaitez appeler la fonction cloud à partir du même projet que la fonction cloud elle-même, vous pouvez initialiser le sdk de firebase et utiliser la méthode onCall. Il gérera tout pour vous:

exports.newRequest = functions.https.onCall((data, context) => {
    console.log(`This is the received data: ${data}.`);
    return data;
})

Appelez cette fonction comme ceci:

// Init the firebase SDK first    
const functions = firebase.functions();
const addMessage = functions.httpsCallable(`newRequest`);

Documents Firebase: https://firebase.google.com/docs/functions/callable

Si vous ne pouvez pas lancer le SDK, voici l'essentiel des autres suggestions:

0
Chronnie

Si vous n'utilisez pas Express ou souhaitez simplement utiliser CORS. Le code suivant aidera à résoudre

const cors = require('cors')({ Origin: true, });   
exports.yourfunction = functions.https.onRequest((request, response) => {  
   return cors(request, response, () => {  
        // *Your code*
    });
});
0
krishnazden