[英]Cloud Functions for Firebase triggering function on CORS preflight request
[英]Preflight error on Firebase cloud functions
當我嘗試從我的網站調用我的雲 function 時,我遇到了預檢錯誤。 我在我的雲 function 中實現了 cors 模塊,我的請求得到了 cors Z099FB995346F31C75E3F6 授權
雲function:
const cors = require('cors')({ origin: true });
exports.CLOUDFUNCTION = functions.https.onRequest(
(request: any, response: any) => {
cors(request, response, async () => {
response.status(200).send('hello');
})
}
);
網站要求:
fetch('FIREBASE_URL/CLOUDFUNCTION',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Headers': 'Authorization'
},
body: JSON.stringify(body), // body is a simple {"variable": "value"}
}
);
錯誤
Access to fetch at 'FIREBASE_URL/CLOUDFUNCTION' from origin 'MYWEBSITE' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
如果您在嘗試通過 URL 訪問您的 function 時遇到 403 禁止錯誤,則您的函數部署有問題,它的配置有問題,或者您在 ZE485903D2A8D2C5DZ 中出錯了
注意:雖然我在此處使用“傳統” require
語句來匹配您的示例,但我鼓勵您對任何新編寫的函數使用更新的 ES6+ JavaScript 功能( const
、 let
、 async
/ await
、 import
等)。
firebase-tools
版本進行部署確保您使用最新版本的firebase-tools
CLI 進行部署。
當v7.7.0
firebase-tools
v7.7.0 發布(2020 年 1 月 15 日)時,在服務器上調用 Cloud Functions 的方式發生了變化,因此只能由經過身份驗證的用戶調用函數。 為了讓 Firebase 用戶可以訪問,必須通過顯式授予allUsers
組Cloud Function Invoker權限來公開這些功能。
在v7.7.0
及更高版本中,這是作為部署的一部分為您完成的。 但是,如果您使用舊版本部署功能,則需要自己配置此權限或使用更新的firebase-tools
版本重新部署。
確保您導出的 function 在部署后命名為您期望的名稱。
特別是,當您的 function 被有意或無意地作為function 組的一部分導出時,請密切注意。 當您將函數拆分為多個文件時,通常會出現這種情況。 在下面的代碼塊中, CLOUDFUNCTION
被導出為myFunctions-CLOUDFUNCTION
而不僅僅是CLOUDFUNCTION
如您所料。
// myFunctions.js
exports.CLOUDFUNCTION = functions.https.onRequest(...);
// index.js (incorrect)
exports.myFunctions = require("./myFunctions.js");
// index.js (correct)
const myFunctions = require("./myFunctions.js");
exports.CLOUDFUNCTION = myFunctions.CLOUDFUNCTION;
檢查您使用的 Cloud Functions URL 是否存在拼寫錯誤。 Cloud Functions URL 中的 Function 名稱區分大小寫。
正確的 URL 應遵循以下格式:
https://<REGION>-<PROJECT_ID>.cloudfunctions.net/<EXPORTED_FUNCTION_NAME>
例子:
https://us-central1-fir-sandbox.cloudfunctions.net/echo
在您的代碼示例中,您傳入NextFunction
而沒有錯誤處理程序。 使用{ origin: true }
時,這“很好”,但是當您開始限制您調用 function 的來源時,您將開始遇到麻煩。 這對於防止您的函數被它們的 URL (其中origin
將是undefined
)直接調用特別方便。 查看文檔或下一部分以獲取更多信息。
const cors = require('cors')({ origin: true });
exports.CLOUDFUNCTION = functions.https.onRequest(
(request, response) => { // <-- don't use `: any` here, as you are disabling the built-in types provided by firebase-functions
cors(request, response, async (err) => {
if (err) {
// Denied by CORS/error with CORS configuration
console.error("CORS blocked request -> ", err);
response.status(403).send("Forbidden by CORS");
return;
}
response.status(200).send('hello');
})
}
);
cors
配置雖然您可以使用cors
package 反映Access-Control-*
標頭,但請考慮明確設置這些服務器端。
const { projectId: PROJECT_ID } = JSON.parse(process.env.FIREBASE_CONFIG);
const cors = require('cors')({
// during emulation, allow localhost & calling directly (i.e. no origin specified);
// at all other times, restrict to deployed hosting sites only
origin: process.env.FUNCTIONS_EMULATOR === "true"
? /^(https?:\/\/localhost:\d+|undefined)$/
: [`https://${PROJECT_ID}.firebaseapp.com`, `https://${PROJECT_ID}.web.app`],
allowedHeaders: ['Content-Type', 'Authorization']
});
exports.CLOUDFUNCTION = functions.https.onRequest(
(request, response) => {
cors(request, response, async (err) => {
if (err) {
// Denied by CORS/error with CORS configuration
console.error("CORS blocked request -> ", err);
response.status(403).send("Forbidden by CORS");
return;
}
response.status(200).send('hello');
})
}
);
這簡化了您的客戶端代碼:
fetch('FIREBASE_URL/CLOUDFUNCTION',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
}
);
如果您的函數需要您代表用戶執行操作,您可以使用Callable Cloud Functions而不是更簡單的 HTTPS 請求函數。 這個版本的 HTTPS Function 處理 CORS,身份驗證,並支持基於 Promise 的數據返回。
注意:這仍然需要 function 如上所述公開。
在服務器端:
exports.CLOUDFUNCTION = functions.https.onCall(async (data, context) => {
if (!context.auth) {
// users must be logged in
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called while authenticated.'
);
}
if (data.variable === undefined)) {
throw new functions.https.HttpsError(
'invalid-argument',
'Parameter "variable" must be a string'
);
}
// you can return a promise here
// this sends back the JSON string "hello world"
return "hello world";
});
在客戶端:
const callFunction = firebase.functions().httpsCallable('CLOUDFUNCTION');
callFunction(body)
.then(
(responseData) => {
// TODO: handle response
},
(functionError) => {
// TODO: handle error
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.