我有一个谷歌云功能。我为我的项目创建了凭据并授权http://localhost&http://localhost:3000作为起源。我还有一个谷歌用户帐户,我将cloudfunctions.functions.invoke角色赋予了它。我通过转到控制台中的云函数并展开"云函数调用器"项目来确认这一点,然后看到我的帐户在那里列出。
我可以用curl成功地访问函数。
curl https://[google cloud-server]/test5-H"授权:承载我的身份令牌">
然而,如果我试图从我的React应用程序调用该函数(我尝试了axios和fetch(,我会得到以下错误。。。。
访问https://[google cloud-server]/test5上的XMLHttpRequest?a=b'来自原点'http://localhost:3000'已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在"access control Allow Origin"标头
有几件事需要注意。。。
- 如果我让所有用户都可以访问该功能,就不会出现CORS问题
- 通过日志记录,我已经确认,在安全的情况下,请求永远不会到达我有CORS代码用于检查飞行前选项的功能。这是有道理的,因为它应该由谷歌保护。但我在谷歌云函数上找到的所有文档都在谈论从函数中处理CORS相关的东西。在我的React应用程序到达我的功能之前,它正在响应它的请求。我不知道在哪里
我在这篇文章中添加了很多标签,因为我真的不知道是哪一层造成了问题。我可能在做一些非常明显/愚蠢的事情,但我没有主意!
云功能。。。。
exports.test5 = (req, res) => {
console.log('function invoked');
// Set CORS headers for preflight requests
// Allows GETs from any origin with the Content-Type header
// and caches preflight response for 3600s
res.set('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
console.log('Determined it is OPTIONS request');
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'GET');
res.set('Access-Control-Allow-Headers', 'Authorization');
res.set('Access-Control-Max-Age', '3600');
res.status(204).send('');
} else {
console.log('Main function body');
res.send('Hello World!');
}
};
来自React客户端的呼叫。。。
const config =
{
params: payload,
headers:
{
Authorization: `bearer ${window.IDENTITY_TOKEN}`
}
};
axios.get(url, config)
.then((res) => {
...
})
.catch((err) => {
handleError(err);
});
有什么想法吗?感谢
CORS preflight OPTION请求没有Authorization标头,并且Cloud函数IAM会预先验证Authorization标头并且在缺少该标头时不会调用该函数。因此,为了提供CORS飞行前响应,您必须允许所有用户访问您的云功能。
编辑
他们更新了文件
如果你想构建一个使用谷歌登录和云功能IAM,您可能需要处理跨来源资源共享(CORS(。CORS飞行前请求发送时没有授权标头,因此它们将在所有非公共HTTP上被拒绝功能。由于飞行前请求失败,主请求将也会失败。
要解决此问题,您可以在以避免CORS飞行前请求。否则,您应该公开您的函数,并在中处理CORS和身份验证功能代码。
或者,您可以部署云端点代理并启用CORS。如果您想要身份验证功能,还可以启用Google ID令牌验证,它将验证这些相同的身份验证代币。