firebase - 为什么在通过 Firebase 身份验证传递 id 令牌时,此 CORS 身份验证的 Google Cloud 函数会返回 403?
问题描述
我已经将谷歌云功能教程中的这个确切功能部署到我的谷歌云项目中。
在客户端,最终用户使用 firebase 身份验证进行signInWithPopup
身份验证。id 令牌是通过user.getIdToken().then(token => { ... // ... }
.
然后通过角度 httpclient 调用对端点进行调用:
const url = 'https://[MY-PROJECT-SUBDOMAIN].cloudfunctions.net/hello_get/';
this.auth.user.getIdToken().then(token => {
const httpOptions = {
headers: new HttpHeaders({
'Authorization': `Bearer ${token}`
})
};
this.http.get(url, httpOptions).subscribe(response => {
console.log(response);
}, error => {
console.error(error);
});
});
对 OPTIONS 预检请求的响应是 403,这让我认为 Google 拒绝了我的 ID 令牌。我在我的函数中添加了一个函数日志hello_get
。似乎该函数甚至没有被调用,因为当返回 403 响应时该日志从未出现。
当“Cloud Functions Invoker”的功能权限设置为 allUsers 时,云功能通过 CORS 可以正常工作,但是一旦我删除该权限并为 allAuthenticatedUsers 添加权限,并尝试Access-Control-Allow-Credentials': 'true'
在云功能中传递令牌,403被退回。
所以 - 似乎根本原因是谷歌拒绝了预检选项请求。如果是这种情况,使用经过身份验证的 firebase 用户调用经过身份验证的谷歌云功能的推荐方法是什么?
注意:我在这里使用谷歌云函数而不是 firebase 函数,因为我们需要使用在 firebase 函数中不可用的 python3 运行时。
解决方案
将 Firebase 身份验证与 Google Cloud 功能结合使用时,用户不会通过 IAM 角色进行身份验证。相反,它们在函数本身内进行身份验证。请注意,根据 Google 的文档,“您将为未经身份验证的请求付费,因为该功能必须执行验证令牌的工作。” 要进行此设置:
(1) 函数上“Cloud Functions Invoker”的 IAM 权限需要向 allUsers 开放(而不是我拥有的 allAuthenticatedUsers)。
(2) 然后使用 firebase_admin 的 auth 库手动完成令牌验证,(docs,供参考和其他语言),如下所示:
from firebase_admin import auth
def your_function(request):
decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']
感谢 Juancki 为我指明了正确的方向。
推荐阅读
- reactjs - 客户使用 Paypal 付款并立即离开网站导致他没有收到商品
- xv6 - 如何在 xv6 中使用 kbgetc
- c++ - Mingw32 无法静态链接到 libgcc_s_dw2-1、libstdc++-6、libwinpthread-1 (Qt 5.7.1)
- bash - 如何替换文本文件中周期性出现的数组
- python - 创建包含给定值和日期范围的所有可能性的字典的最佳方法是什么?
- console - 自几周前 Google 更新以来,是否有人在他们的操作中也遇到过故障?
- go - 使用切片的动态结构(包含外键)和 go-gorm 将数据插入数据库
- xslt - 如何使用 XSLT 将所有标题文本转换为标题大小写?
- javascript - 如何在 React 的 return 语句中使用获取结果?
- tensorflow - 我想在我的自定义层中使用 keras 层,但我无法将层的输出作为张量而不是对象返回