为什么在通过 Firebase 身份验证传递 id 令牌时,此 CORS 身份验证的 Google Cloud 函数会返回 403? [英] Why is this CORS authenticated Google Cloud Function returning a 403 when passing an id token from Firebase authentication?

查看:20
本文介绍了为什么在通过 Firebase 身份验证传递 id 令牌时,此 CORS 身份验证的 Google Cloud 函数会返回 403?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已从 google 云函数教程 到我的谷歌云项目.

I've deployed this exact function from the google cloud function tutorial to my google cloud project.

在客户端,最终用户使用 firebase signInWithPopup 身份验证进行身份验证.id 令牌是通过 user.getIdToken().then(token => { ...//... } 从结果用户获取的.

On the client side an end user is authenticated using the firebase signInWithPopup authentication. The id token is taken from the resulting user via user.getIdToken().then(token => { ... // ... }.

然后通过角度 httpclient 调用对端点进行调用:

A call to the endpoint is then made via an angular httpclient call:

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 响应时该日志从未出现.

The response is a 403 to the OPTIONS preflight request which makes me think Google is rejecting my ID token. I've added a function log in my hello_get function. It appears the function doesn't even get called because this log is never appearing when the 403 response is returned.

当Cloud Functions Invoker"的功能权限设置为 allUsers 时,云功能通过 CORS 可以正常工作,但是一旦我删除该权限并为 allAuthenticatedUsers 添加权限,并尝试使用 Access 传递令牌-Control-Allow-Credentials': 'true'在云端函数中,返回403.

The cloud function works fine via CORS when the function permissions for 'Cloud Functions Invoker' are set to allUsers, but as soon as I delete that permission and add permissions for allAuthenticatedUsers, and try to pass a token with Access-Control-Allow-Credentials': 'true' in the cloud function, a 403 is returned.

所以 - 似乎根本原因是谷歌拒绝了预检 OPTIONS 请求.如果是这种情况,使用经过身份验证的 firebase 用户调用经过身份验证的谷歌云功能的推荐方法是什么?

So - it seems like the root cause is google rejecting the preflight OPTIONS request. If this is the case, what is the recommended way to call an authenticated google cloud function with an authenticated firebase user?

注意:我在这里使用谷歌云函数而不是 firebase 函数,因为我们需要使用 firebase 函数中不可用的 python3 运行时.

Note: I'm using google cloud functions instead of firebase functions here because we need to use the python3 runtime which is not available in firebase functions.

推荐答案

将 Firebase 身份验证与 Google Cloud 功能结合使用时,用户不会通过 IAM 角色进行身份验证.相反,它们在函数本身内进行身份验证.请注意,根据 Google 的文档,您将为未经身份验证的请求付费,因为该功能必须执行验证令牌的工作."要进行设置:

When using Firebase Authentication with Google Cloud functions, users are not authenticated via IAM roles. Instead, they are authenticated within the function itself. Note, per Google's docs, "you will be billed for unauthenticated requests since the function must do work to validate the token." To set this up:

(1) 函数上Cloud Functions Invoker"的 IAM 权限需要向 allUsers 开放(而不是我拥有的 allAuthenticatedUsers).

(1) The IAM permissions for "Cloud Functions Invoker" on the function need to be opened up to allUsers (as opposed to allAuthenticatedUsers which I had).

(2) 然后使用 firebase_admin 的身份验证库手动完成令牌验证,(docs,供参考和其他语言)像这样:

(2) The token verification is then done manually using firebase_admin's auth library, (docs, for reference & other languages) like so:

from firebase_admin import auth

def your_function(request):
    decoded_token = auth.verify_id_token(id_token)
    uid = decoded_token['uid']

感谢 Juancki 为我指明了正确的方向.

Thanks to Juancki for pointing me in the right direction.

这篇关于为什么在通过 Firebase 身份验证传递 id 令牌时,此 CORS 身份验证的 Google Cloud 函数会返回 403?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆