授权从 Firebase Cloud Function 访问 Google Cloud Translate?

2023-12-03

我正在尝试编写一个调用 Google Cloud Translate 的 Firebase Cloud Function。我收到此错误:

Error: 7 PERMISSION_DENIED: Cloud IAM permission 'cloudtranslate.generalModels.predict' denied. 

我的凭据似乎没有从 Firebase Cloud Function 传递到 Google Cloud Translate。我设置了一个用户管理的服务帐户,首先我尝试从 CLI 进行部署:

firebase deploy --only functions:ENtranslateES --service-account [email protected]

这引发了这个错误:

error: unknown option '--service-account'

然后我尝试了这个:

gcloud functions deploy ENtranslateES --service-account [email protected]

那行得通。我在 CLI 上收到了冗长的响应,没有错误,并且我在 Google Cloud Console 中看到 Cloud FunctionENtranslateES上次部署是在我执行该命令时。

触发 Firebase Cloud Function 继续返回PERMISSION_DENIED: Cloud IAM permission error.

这是我的代码:

exports.ENtranslateES = functions.firestore.document('Users/{userID}/English/Translation_Request').onUpdate((change) => { 
    const { TranslationServiceClient } = require('@google-cloud/translate').v3;
    const translationClient = new TranslationServiceClient();
    const projectId = 'my-awesome-app';
    const location = 'global';
    const text = 'Hello, world!';

    async function translateText() {
        const request = {
            parent: `projects/${projectId}/locations/${location}`,
            contents: [text],
            mimeType: 'text/plain', // mime types: text/plain, text/html
            sourceLanguageCode: 'en',
            targetLanguageCode: 'es',
        };

        const [response] = await translationClient.translateText(request);

        for (const translation of response.translations) {
            console.log(`Translation: ${translation.translatedText}`);
        }
    }

    return translateText()

});

我还设置了从 Postman 到 Google Cloud Translate 的 POST 查询。我输入了授权属性Client ID, Client Secret, Auth URL, Access Token URL等等。邮递员查询有效。我应该把我的Client ID, Client Secret我的 Firebase Cloud Function 代码中的 等?根据我的阅读,如果我使用服务帐户部署该功能,则似乎没有必要这样做。


我成功了!这是我学到的。

我使用 IAM 服务帐户将 Firebase Cloud Function 连接到 Google Cloud Translate。这些说明也适用于 Google Cloud Functions 和其他 Google Cloud 服务。

概述保护云功能说云功能安全可以是基于身份的 or 基于网络的。在基于身份的类别中,您可以使用用户帐号(用户名和密码)或服务帐户。服务帐户似乎是首选方法,因此在这个答案中我将只讨论服务帐户。

IAM 和服务账户

Google Cloud Console 一开始可能会让人不知所措。您从一个用户帐户开始,这可能是您的 Gmail 地址。然后你创建一个组织,并在你的组织中创建一个项目。

然后寻找IAM & Admin. IAM代表身份访问管理。服务帐户看起来像电子邮件地址。这提供了一个identity到 Googleverse 中的云功能。换句话说,为您的 Cloud Functions 创建服务帐户使其能够与 Google Cloud 中的其他内容进行交互。该文件函数恒等式讨论服务帐户的这个方面。

服务帐户有校长 and roles。您的服务帐户之一应该是您的电子邮件地址以及您的姓名和角色Owner。该文件使用 IAM 授权访问s 显示如何向服务帐户授予主体和角色。

将其他服务帐户视为您的仆从,他们听从您的命令。有些是在您注册 Google Cloud 服务时自动创建的。

当您想做一些事情时,您可以创建新的服务帐户。例如,我编写了一个将英语翻译成西班牙语的 Firebase Cloud Function。我希望这个函数调用 Google Cloud Translate。服务帐户旨在完成一件事。服务帐户是以以下结尾的电子邮件地址iam.gserviceaccount.com.

因为服务帐户执行某些操作,所以您可以将角色分配给服务帐户。在本例中,我的服务帐户调用 Google Cloud Translate,因此我为其分配角色Cloud Translation API User.

因为服务帐户确实只有一件事你分配一个作用有限到服务帐户。例如,我的翻译服务帐户无法在 Google Cloud Dataplex 中执行操作。它也不会成为Cloud Translation API Editor or Admin。这只是一个Cloud Translation API User minion.

建立一个服务帐户

在您的 Google Cloud Console 下IAM & Admin寻找Service Accounts在左侧边栏中。在顶部栏中查找+ CREATE SERVICE ACCOUNT.

您可以为您的服务帐户命名任何您想要的名称。我建议将其命名为您的 Firebase 云函数的名称。这清楚地表明了服务帐户的用途。为了更加清楚地写在Service account description就像是This service account hooks up the Firebase Cloud Function SuperTranslator to Google Cloud Translate.在将来的某个时候,您将拥有太多的服务帐户,并且您会想要删除一些。

Click DONE.

将角色分配给服务帐户

现在点击IAM under IAM & Admin在左侧边栏中。您的服务帐户应该在那里,因为服务帐户是一种特殊类型的 IAM。

在右侧单击与您的服务帐户关联的铅笔。在下面Assign roles滚动浏览数百个选项,找到您希望服务帐号使用的 Google Cloud 产品或服务。选择产品或服务后,选择角色。

正如我之前提到的,分配使您的功能能够正常工作的最低角色。就我的翻译功能而言,有四种选择:Admin, Editor, User, and Reader。卑微者ReaderMinions 只允许阅读策略和组织描述。UserMinions 可以访问 Google Cloud 服务。这就是我希望我的服务帐户执行的操作。Editor可以编辑政策和组织描述以及Admin拥有对政策和组织描述的完全访问权限。我不希望这个服务帐户做那些事情。

回到你的IAM页面,您会在右侧注意到每个 IAM 的计数多余的权限(穿蓝色衣服)。这可能是一个Admin仅被要求执行的角色User级别的东西。单击蓝色三角形有时会建议您采取一些措施来减少多余的权限。换句话来说,IAM 的目的是给予每个 Minion 足够的权限来完成其工作,而不是更多。

下载您的服务帐户 JSON 文件

现在您将把凭据下载到您的计算机上。在您的 Google Cloud Console 中,转到IAM and admin, then Service accounts。单击您想要的服务帐户。

选择KEYS标签。点击ADD KEYS按钮并选择Create new key。选择JSON单选按钮。将打开一个模式窗口,询问您将密钥下载到哪里。我有一个用于存放服务帐户密钥的文件夹:

ProjectDirectory/environments/service_account_keys

如果您打开密钥文件,您将看到:

{
  "type": "service_account",
  "project_id": "my-project",
  "private_key_id": "12345abcde",
  "private_key": "-----BEGIN PRIVATE KEY-----\n1673randomcharacters...=\n-----END PRIVATE KEY-----\n",
  "client_email": "[email protected]",
  "client_id": "12345",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/google-cloud-service%40my-project.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}

不要尝试获取现有密钥的服务帐户密钥 JSON。据我所知,这是不可能的。如果您需要下载服务帐户密钥,请创建一个新密钥。他们是免费的。

将您的云功能连接到您的服务帐户密钥

这是疯狂的、未记录的部分。 Google Cloud 支持人员甚至不知道这一点。

将您的 Cloud Function 连接到您的服务帐户密钥以在Firebase 模拟器, 做一个TranslationServiceClient(options) object:

const options = {
  keyFilename: '/Users/TDK/VisualStudioCodeProjects/MyProjectDirectory/environments/service_account_keys/my-project-12345.json',
};
import { TranslationServiceClient } from '@google-cloud/translate';
const translationClient = new TranslationServiceClient(options);

您将服务帐户密钥的路径作为参数传递TranslationServiceClient(options). Your options对象具有单一属性,keyFilename。该属性的值是您的服务帐户密钥的路径。我更喜欢绝对路径,但如果您愿意,也可以使用相对路径。

这是文档为了TranslationServiceClient 类型。您可以看到还有更多属性。看起来你可以使用credentials属性将服务帐户电子邮件及其私钥放入您的云功能中。这将是一个坏主意,因为您可能会无意中将您的云功能上传到不安全的存储库并将您的私钥暴露给公众。

将您的 Cloud Function 连接到您的服务帐户密钥以在Firebase 云, 做一个GOOGLE_APPLICATION_CREDENTIALS持续的:

import { TranslationServiceClient } from '@google-cloud/translate';
const translationClient = new TranslationServiceClient();
export const GOOGLE_APPLICATION_CREDENTIALS = '/Users/TDK/VisualStudioCodeProjects/MyProjectDirectory/environments/service_account_keys/my-project-12345.json';

不要问我花了多长时间才发现 Firebase 模拟器和云需要不同的代码。

使用服务帐户部署您的云功能

通常我们像这样部署 Firebase Cloud Functions:

firebase deploy --only functions:myAwesomeFunction

还有另一种部署 Cloud Functions 的方法,它允许您连接服务帐户:

gcloud functions deploy myAwesomeFunction --service-account [email protected]

如果您使用以下方式部署云功能gcloud并且您不需要在代码中连接凭据密钥文件的服务帐户。这很容易并且看起来安全性更高。

然而......上次我尝试这样做时,我收到一个错误,说它找不到lib/index.js文件。这是指定的文件main财产在functions/package.json。当你跑步时npm run build在部署 Cloud Function 之前,TypeScript 会将您的代码转换为 JavaScript,从src/index.ts to lib/index.js. gcloud以前可以找到JavaScript文件,但现在不能了。

而 Firebase 团队从未实现过这一点。你不能这样做:

firebase deploy --only functions:myAwesomeFunction --service-account [email protected]

显然这不建议用于 Firebase Cloud Functions。

我没有看到这个答案中引用的文档。因此,这可能不是保护服务帐户访问的最佳方法。

测试你的功能

调用您的函数并查看日志,您应该会看到 Firebase Cloud 函数执行。

请记住使用以下命令转译你的 TypeScriptnpm run build在模拟器中调用函数之前。

使用服务帐户修复 CORS 错误

有时,您在调用云函数时会遇到 CORS 错误。您可以使用服务帐户来修复 CORS 错误。选择您的项目服务帐户([email protected]),创建一个新密钥,并将其保存到您的environments。采取apiKey属性,将其作为参数传递defineSecret(),然后使用以下命令调用云函数apiKey:

import { defineSecret } from "firebase-functions/params";
const apiKey = defineSecret("12345");
export const CallUppercase = onCall({ secrets: [apiKey] }, (request) => {
  ...
});

通常,这些不是 CORS 错误,而是其他错误,例如您没有将 Cloud Function 部署到云,或者在模拟器中调用 Cloud Function 之前没有对其进行转译。

工作负载身份联合

当您创建服务帐户密钥时,您会看到一个框,上面写着

如果服务帐户密钥遭到泄露,可能会带来安全风险。我们 建议您避免下载服务帐户密钥,而是 使用工作负载身份联合。您可以了解更多有关 在 Google Cloud 上验证服务帐号的最佳方式here.

后一个链接转到博客文章选择在 Google Cloud 上使用和验证服务帐号的最佳方式。这篇博文讨论了四个用例:

  1. 将服务帐号附加到 Cloud Functions、Cloud Run 以及 Google Cloud 上部署的其他应用程序

  2. 将服务帐户附加到 Kubernetes Pod

  3. 将服务帐号附加到未在 Google Cloud 上运行的应用

  4. 下载服务帐户密钥

我们只是做了后者,只有当前者选项不可用时才建议这样做。第一个选项似乎是谷歌推荐的。这工作负载身份联合文档讨论了 Amazon AWS、Microsoft Azure 和其他云计算平台,但没有讨论 Google Cloud Functions。这保护云功能文档是关于授权谁可以调用您的 Cloud Functions,而不是授权您的 Cloud Functions 调用其他 Google Cloud 服务。我找不到比下载的服务帐户密钥更好的连接 Cloud Functions for Cloud Services 的文档。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

授权从 Firebase Cloud Function 访问 Google Cloud Translate? 的相关文章

随机推荐

  • 新版本的c++

    C 是否会推出新版本 何时推出 C C 0X 的创建者常见问题解答 http www2 research att com bs C 0xFAQ html 问题 C 0x什么时候成为正式标准 但 C 0X 确实在某种程度上存在于各种编译器中
  • 如何在Three20的AppDelegate中添加全局右栏按钮(UINavigationController)

    我想在全局 AppDelegate 中添加一个全局右栏按钮 这样我的所有视图控制器都会自动具有此按钮 我在AppDelegate中添加了 navigator window rootViewController navigationContr
  • 将具有重复字符的字符串拆分为列表

    我对正则表达式没有太多经验 但我已经阅读了很多相关内容 假设有一个字符串s 111234 我想要一个列表 其中字符串分为L 111 2 3 4 我的方法是让一组检查它是否是数字 然后检查该组是否重复 像这样的东西 L re findall
  • JS:获取contentEditable div中所有选定节点的数组

    你好 我使用 contentEditable 已经有一段时间了 我想我已经很好地处理它了 我回避的一件事是如何获取对部分或完全在用户选择范围内的所有节点的引用数组 有人有主意吗 可以从以下几点开始
  • 导航到不同的 html 页面时,jQuery Mobile 页面事件不会触发

    我正在尝试使用导航到不同的 html 页面 mobile changePage PlayGame html transition slideup true true PlayGame html 正在转换为 但是 以下内容均未触发 docum
  • 我们如何在单个 JSF 页面中使用多个 标记或 标记?

    我的问题是 我在一个 JSF 页面中有 2 个表单 每个表单都有其
  • 如何使用 UIGestureRecognizer 检测圆周运动

    我希望能够检测到某人的手指在屏幕上画圆周运动 就像他们在画 O 一样 这可以通过 UIGestureRecognizer 实现吗 我认为这个问题的答案取决于您对圆周运动的定义以及您打算如何使用它 例如 您想知道用户手指沿着圆移动了多少度 或
  • 根据变量值生成数据总和

    我有类似这样的数据 Hosp Score Var1 Var2 Var3 1 0 5 3 0 1 1 10 8 1 1 2 11 8 2 1 3 5 3 2 2 0 6 4 0 2 2 10 6 1 2 3 10 7 2 3 1 4 3 2
  • 当条件不满足时重置 pandas cumsum [重复]

    这个问题在这里已经有答案了 我经历了不同的 stackoverflow 问题并最终发布它 因为我无法解决我面临的问题之一 我有一个如下所示的数据框 A B C group1 group1 c 12 group1 group1 c 12 gr
  • 从 PostgreSQL 函数运行 Python 脚本

    每次在 PostgreSQL 表上执行更新或插入操作时 我都面临一个 小 问题 该脚本将提取更新或插入的数据并将其写入文件 环境数据 乌班图18 04 仿生海狸 PostgreSQL 10 和 Python 3 6 SELECT FROM
  • MinGW64 无法进行 32 字节堆栈对齐(Windows x64 上的 AVX 所需),轻松解决或切换编译器?

    我正在尝试使用 AVX 指令和 Windows 64 位 我对 g 编译器很满意 所以我一直在使用它 但是 报告了一个大错误here并提出了非常粗略的解决方案here 基本上 m256 变量无法在堆栈上对齐才能与 avx 指令一起正常工作
  • 如何确定OGG文件的长度

    我正在制作节奏游戏 我需要一种快速方法来获取 ogg 文件的长度 我能想到的唯一方法是非常快速地传输文件而不播放它 但如果我有数百首歌曲 这显然是不切实际的 另一种方法是将文件的长度存储在某种属性文件中 但我想避免这种情况 我知道一定有某种
  • 无法在模拟器中启动 AVD:未找到 QT 库

    我是 Android Studio 新手 在使用模拟器时遇到问题 当我尝试运行时 它不断崩溃并显示 无法在模拟器中启动 AVD 6816 错误 android qt qt setup cpp 28 在以下位置找不到 Qt 库 C Users
  • Cocoa Interface Builder 的“属性检查器”类似窗口

    我正在制作一个 Cocoa 应用程序 我想要一个像 Interface Builder 中的 属性检查器 这样的面板 因此 顶部有大标签和可折叠 可展开的组 有谁知道我该怎么做 这是属性检查器的图像 属性检查器 http developer
  • PHP mysqli_fetch_all 给我一个空白屏幕

    我刚刚将一些内容从本地计算机推送到实时站点 但到处都是空白页面 当我使用所有东西时 我将问题追踪到 mysqli fetch all 它为什么要这样做 我该如何解决它 如果我使用 mysqli fetch array 或 mysqli fe
  • 如何在 Flutter 中解码 JSON?

    如何在 Flutter 中解码 JSON 问题很简单 但答案却不简单 至少对我来说是这样 我有一个使用大量 JSON 字符串的项目 基本上 应用程序和服务器之间的整个通信都是通过 JSON 进行的 我一直在使用JSON decode jso
  • 使用 GPUImage 过滤视频

    我在用着GPUImage在我的应用程序中并尝试过滤视频 实时视频过滤效果良好 当我尝试从文件系统将视频读入内存并使用发布在日落湖软件教程页面和 SimpleVideoFileFilter 演示中 EDIT 我意识到我原来的帖子可能没有提出足
  • pop_back()返回值?

    为什么不pop back 有返回值吗 我用谷歌搜索了一下这个问题 发现它可以提高效率 这是标准中如此规定的唯一原因吗 效率与之几乎没有关系 或者实际上没有关系 这个设计的结果是汤姆 卡吉尔的一篇重要论文上世纪 90 年代出版 当时引起了相当
  • Go类型用于函数调用

    关键词如go and defer期待一个函数调用作为参数 是否有可用的类型可以以相同的方式使用 例如 编写一个需要函数调用 而不是函数 作为参数的函数 不 那里没有 你不能对你的函数做同样的事情 go and defer由语言规范支持 并且
  • 授权从 Firebase Cloud Function 访问 Google Cloud Translate?

    我正在尝试编写一个调用 Google Cloud Translate 的 Firebase Cloud Function 我收到此错误 Error 7 PERMISSION DENIED Cloud IAM permission cloud