web-dev-qa-db-ja.com

Firebaseのクラウド機能でCORSを有効にする

私は現在Firebase用の新しいCloud Functionsの使い方を学んでいますが、私が抱えている問題はAJAXリクエストを通して書いた関数にアクセスできないということです。 「アクセス制御許可の発生元がありません」というエラーが表示されます。これが私が書いた関数の例です:

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

関数はこのURLにあります。 https://us-central1-fba-shipper-140ae.cloudfunctions.net/test

Firebaseのドキュメントでは、CORSミドルウェアを関数内に追加することを提案しています。試してみましたが、動作しません。 https://firebase.google.com/docs/functions/http-events

これが私のやり方です。

var cors = require('cors');    

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

何がおかしいのですか?私はこれでどんな助けにでも感謝するでしょう。

更新:

Doug Stevenson の回答が助けになりました。 ({Origin:true})を追加して問題を解決しました。response.status(500)response.status(200)に変更する必要もありましたが、最初は完全に見逃していました。

81

Firebaseチームが提供するCORSの使用方法を示す2つの サンプル関数 があります。

2番目のサンプルは、現在使用している方法とは異なる方法でcorsを使用します。

また、サンプルに示すように、このようにインポートすることを検討してください。

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

このようにクラウド関数でCORSを設定できます。response.set('Access-Control-Allow-Origin', '*');corsパッケージをインポートする必要はありません。

27

TypeScriptでこれをやろうとしている人のためにこれはコードです:

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
});
21
Yayo Arellano

しばらくしてからこれをグーグルする人のために、もう1つ情報を追加します。firebase hostingを使用している場合は、たとえば(firebase_hosting_Host)/ api/myfunctionのようなURLを( firebase_cloudfunctions_Host)/ doStuff関数このように、リダイレクトは透過的でサーバーサイドなので、あなたはコアを扱う必要はありません。

Firebase.jsonの書き換えセクションでそれを設定できます。

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

私は@Andreysが彼自身の質問に答えることに少し追加しています。

cors(req, res, cb)関数でコールバックを呼び出す必要がないように思われるので、すべてのコードをコールバックに埋め込むことなく、関数の先頭にあるcorsモジュールを呼び出すだけで済みます。後でcorsを実装したい場合は、これははるかに速くなります。

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

冒頭の記事で述べたように、CORを初期化することを忘れないでください。

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

15
Jaap Weijland

CORSソリューションは私のために働きませんでした...今まで!

他の誰かが私がやったのと同じ問題に遭遇したかどうかわからないが、私は私が見つけた例から5つの異なる方法のようにCORSをセットアップし、何もうまくいかないようだった。私はそれが本当にバグであるかどうかを確かめるためにPlunkerで最小限の例を設定しました、しかし例は美しく走りました。私はそれが私に何かを伝えることができるかどうか見るためにfirebase機能ログ(firebaseコンソールにある)をチェックすることにしました。 私は自分のノードサーバーコードに2、3のエラーがありましたCORS関連ではありません、デバッグしたときCORSエラーメッセージを私にリリースしました。 CORSとは無関係のコードエラーがCORSエラー応答を返す理由はわかりませんが、それが間違ったウサギの穴を何時間もの間私を導いてくれました...

tl; dr - CORSソリューションが機能しない場合はfirebaseの機能ログを確認し、エラーがあればデバッグします。

8
tbone849

私はそのことについて少しだけ出版したところです。

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

一般的には、Express CORS package を使うべきです。これはGCF/Firebase Functionsの要件を満たすために少し手を加える必要があります。

それが役立つことを願っています!

6
mhaligowski

これは役に立つかもしれません。 express(カスタムURL)でfirebase HTTPクラウド機能を作成しました

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);

書き換えセクションを追加したことを確認してください

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

私は私の要求で承認を持っているので、この方法だけが私のために働く:

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

apponRequestに渡すときに同じ問題を抱えていたのは価値があることです。私は、この問題がfirebase機能のリクエストURLの末尾のスラッシュであることに気付きました。 Expressは'/'を探していましたが、関数[project-id].cloudfunctions.net/[function-name]の末尾にスラッシュがありませんでした。 CORSエラーは偽陰性でした。末尾のスラッシュを追加すると、期待したとおりの応答が得られました。

2
shadyhill

私のような人がいる場合:クラウド関数と同じプロジェクトからクラウド関数を呼び出す場合、firebase sdkを初期化してonCallメソッドを使用できます。それはあなたのためにすべてを処理します:

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

この関数を次のように呼び出します。

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

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

SDKを初期化できない場合は、他の提案の本質がここにあります。

0
Chronnie

Expressを使用していない場合、または単にCORSを使用したい場合次のコードは解決に役立ちます

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