使用刷新令牌对 Firebase 管理员进行身份验证

Using a refresh token to authenticate Firebase Admin

我想使用刷新令牌对 firebase-admin 进行身份验证。以下是 Firebase 文档对此的评价:

The Admin SDKs also provide a credential which allows you to authenticate with a Google OAuth2 refresh token:

var refreshToken; // Get refresh token from OAuth2 flow

admin.initializeApp({
  credential: admin.credential.refreshToken(refreshToken),
  databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});

Source

所以我尝试这样做:

const admin = require('firebase-admin')

admin.initializeApp({
  credential: admin.credential.refreshToken({
    refreshToken: '6/m-jebiu2398bydhl2lhjdUehkEWlhewer', // fake value for security
    clientId: '2398757349827-bkewjeo7b092j2083hodb0u923.apps.googleusercontent.com', // fake value for security
    clientSecret: 'ijboi3290u8eu2132', // fake value for security
    type: 'authorization_code'
  }),
  databaseURL: 'https://<database>.firebaseio.com/' // fake value for security
})

admin.database().ref('/test2').once('value')
  .then(snap => snap.val())
  .then(console.log.bind(console))

(我运行这个用Node.js)

注意 admin.credential.refreshToken 需要一个对象。文档(指南和参考)没有这样说。我只是通过查看 firebase-admin 的来源才发现这个事实(以及对象的形状)。

这段代码没有抛出任何错误,但它不起作用。每隔几秒,控制台中就会出现一个警告,console.log 永远不会在 .then 中调用。 (添加 .catch 不会改变任何东西,.catch 也不会被触发)。

FIREBASE WARNING: Provided authentication credentials for the app named "[DEFAULT]" are invalid. This usually indicates your app was not initialized correctly. Make sure the "credential" property provided to initializeApp() is authorized to access the specified "databaseURL" and is from the correct project.

在进行更多挖掘后,这个警告来自@firebase/database,而不是 firebase-admin。当 Firebase 数据库拒绝身份验证(来自 websocket 连接)时发生。

事实上,firebase-admin成功创建了access token,只是数据库拒绝了。

我尝试了两种刷新令牌:

  1. 从第三方 Google 应用程序(与数据库无关)创建的刷新令牌。当然我也提供了相关的客户端id/secret。 我假设 google 用户必须有权访问项目才能像这样进行身份验证。此方法会产生上述警告。
  2. 从 Firebase 项目(拥有数据库的项目)创建的刷新令牌。同样,客户端 id/secret 来自创建刷新令牌的项目。这也会产生上述警告。

说了这么多,我有两个问题:

  1. 如果不是第三方应用程序或 Firebase 创建的 google 应用程序,我应该从哪里获取客户端 id/secret 和刷新令牌?
  2. 传递给 admin.credential.refreshTokentype 是什么?空值会引发错误,但实际上任何其他字符串值似乎都没有区别。 type 似乎没有在 firebase-admin 的源代码中使用。

现在,您可能会问“为什么 您想使用刷新令牌对 firebase-admin 进行身份验证?”。如果项目的 owner/authorized 用户允许,我想创建一个可以访问任意数据库的网络应用程序。我相信这是最好的方法。

感谢您花时间阅读所有这些内容。我很感激你的任何建议!

Admin SDK 期望的刷新令牌格式特定于 Google 产品。这是 gcloud SDK. If you have gcloud SDK installed, and performed a login 使用的文件格式,使用它在 ~/.config/gcloud/application_default_credentials.json 创建所需的刷新令牌文件。您可以将此文件路径或其内容对象传递给 admin.credential.refreshToken()type 字段的值按照惯例是 authorized_user,但 Node SDK 并不像您注意到的那样真正关心。

刷新令牌凭据使 SDK 能够作为个人用户进行身份验证。这在开发和测试期间很有用(将开发人员的凭据用作应用程序默认凭据的 stand-in),但据我所知没有生产应用程序。您可能应该为您的用例使用服务帐户。

以下对我有用(使用我自己的刷新令牌访问我拥有的数据库):

const admin = require('firebase-admin')
admin.initializeApp({
  credential: admin.credential.refreshToken('~/.config/gcloud/application_default_credentials.json'),
  databaseURL: "https://<DB_NAME>.firebaseio.com",
});
admin.database().ref().once('value')
  .then(snap => {
    console.log(snap.val());
  })