首页 > 解决方案 > 为什么在通过 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 运行时。

标签: firebasefirebase-authenticationgoogle-cloud-functions

解决方案


将 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 为我指明了正确的方向。


推荐阅读