"Caller does not have permission" 尝试使用 Firebase Admin SDK 创建自定义令牌

"Caller does not have permission" trying to create custom token with Firebase Admin SDK

错误

调用 admin.auth().createCustomToken() 时出现以下错误:

Error: The caller does not have permission; Please refer to https://firebase.google.com/docs/auth/admin/create-custom-tokens for more details on how to use and troubleshoot this feature.

根据提供的文档,我认为我用来初始化 Firebase Admin SDK 的服务帐户没有足够的权限。我不相信是这样,所以我想问一下,看看我是否遗漏了什么。

配置

Firebase Admin SDK 在后端初始化如下:

admin.initializeApp({
  serviceAccountId: 'firebase-adminsdk-xxxxx@my-project-id.iam.gserviceaccount.com'
});

从技术上讲,该值是从环境变量中引用的,但我已确认该值是正确的。

正在使用的服务帐户具有以下角色:

roles/firebase.sdkAdminServiceAgent
roles/iam.serviceAccountTokenCreator

根据文档,创建自定义令牌所需的权限是 iam.serviceAccounts.signBlob。根据此输出,此权限是 iam.serviceAccountTokenCreator 角色的一部分:

❯ gcloud beta iam roles describe roles/iam.serviceAccountTokenCreator
description: Impersonate service accounts (create OAuth2 access tokens, sign blobs
  or JWTs, etc).
etag: AA==
includedPermissions:
- iam.serviceAccounts.get
- iam.serviceAccounts.getAccessToken
- iam.serviceAccounts.getOpenIdToken
- iam.serviceAccounts.implicitDelegation
- iam.serviceAccounts.list
- iam.serviceAccounts.signBlob
- iam.serviceAccounts.signJwt
- resourcemanager.projects.get
- resourcemanager.projects.list
name: roles/iam.serviceAccountTokenCreator
stage: GA
title: Service Account Token Creator

最后,出现问题的代码如下:

try {
  const loginToken = await admin.auth().createCustomToken(uid);
  return response(200).json({ loginToken });
} catch (err) {
  ...
}

uid 来自通过 GoogleUser 凭据登录用户 - 提供的 uid 被确认是准确的,并且当引用同一服务帐户的 JSON 密钥文件时,此流程在本地工作。

服务器 运行 在 GKE 上,以防出现集群权限错误。

如有任何帮助,我们将不胜感激!

编辑 - 已解决 Hiranya 的回答起到了作用——K8s 部署配置了一个服务帐户,其初衷只是为了启用云 SQL 代理。为该服务帐户授予 serviceAccountTokenCreator 角色解决了该问题。

您需要确保授权 SDK 的服务帐户(不是指定为 serviceAccountId 的帐户)具有令牌创建者角色。这是 auto-discovered 由 Google 应用程序默认凭据提供的服务帐户。对于 Cloud Functions,这是名为 {project-name}@appspot.gserviceaccount.com 的服务帐户。您需要找出 GKE 的等效服务帐户并授予其令牌创建者角色。