以管理员身份使用自定义令牌向 FB DB 发出 REST 请求

Posted

技术标签:

【中文标题】以管理员身份使用自定义令牌向 FB DB 发出 REST 请求【英文标题】:Using Custom Tokens to make REST requests to FB DB as an admin 【发布时间】:2016-09-22 09:44:42 【问题描述】:

我正在迁移到新的数据库和 3.0 客户端库。我正在更新生成自定义身份验证令牌(在我们的服务器上)的部分,以执行 PATCH 以更新 Firebase 数据库中的资源。

这些 PATCH 请求过去是由我们的服务器使用 admin 声明向 Firebase 发出的:https://www.firebase.com/docs/rest/guide/user-auth.htm

对于新数据库,我正在生成 JWT 令牌(使用 ruby-jwt),如下所示:

payload = 
  aud: "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
  claims: custom_claims.merge( admin: true ),
  exp: now_seconds + (60 * 60), # Maximum expiration time is one hour
  iat: now_seconds,
  iss: service_account_email,
  sub: service_account_email,
  uid: uid


JWT.encode(payload, private_key, "RS256")

使用此令牌向 Firebase 数据库发出 PATCH 请求失败,并显示:Missing claim 'kid' in auth header

【问题讨论】:

跨帖:groups.google.com/forum/#!topic/firebase-talk/XTJfiltow-I 【参考方案1】:

在新的 Firebase 中,您需要直接使用服务帐号来创建管理访问凭据。这是一个 Node.js sn-p,它展示了如何对数据库进行 REST 调用:

// key.json is a service account key downloaded from the Firebase Console
var key = require('./key.json');

var google = require('googleapis');
var request = require('request');

var DATABASE_URL = 'https://<databaseName>.firebaseio.com';

var jwtClient = new google.auth.JWT(key.client_email, null, key.private_key, [
  'https://www.googleapis.com/auth/userinfo.email',
  'https://www.googleapis.com/auth/firebase.database'
]);

jwtClient.authorize(function(err, tokens) 
  request(
    url: DATABASE_URL + '/.json',
    method: 'GET',
    headers: 
      'Authorization': 'Bearer ' + tokens.access_token
    
  , function(err, resp) 
    console.log(resp.body);
  );
);

要在 Ruby 中执行相同操作,您可以查看 googleauth gem 以使用服务帐户凭据获取访问令牌。

【讨论】:

是否可以包含自定义声明,可从我的数据库规则访问,例如使用 Firebase 2.x 自定义 REST 令牌? 您可以使用 auth_variable_override 查询参数添加自定义声明(只需使其成为有效的 JSON 对象)。 您的意思是作为 REST 请求本身的查询参数?那怎么安全?我的客户端不受信任(物联网设备),我需要一种安全的方式来限制其对 Firebase 数据库的访问。事实上,这个(显然是未记录的)功能在我的整个安全模型中都是一个整体。我希望我误解了你! 您应该绝对不使用服务帐户来授权不受信任的物联网设备;我误解了你的用例。目前 3.x SDK 缺少 Node.js 解决方案,我们建议您现在使用 2.x SDK,我们将在不久的将来推出解决方案。 感谢您的澄清。我期待尽快找到解决方案。【参考方案2】:

这相当于 Michael Bleigh 使用 ruby​​ googleauth 模块的答案:

require 'googleauth'

scopes = [ 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/firebase.database']
auth = ::Google::Auth.get_application_default(scopes)
auth_client = auth.dup
auth_client.sub = "service-account-email-here@yourapp.iam.gserviceaccount.com"
token = auth_client.fetch_access_token!

您还需要将 GOOGLE_APPLICATION_CREDENTIALS 环境变量设置为您的服务帐户 JSON 文件的路径。 auth_client.sub 的值来自此 JSON 文件中的 client_email

当然,如上所述,这仅在您控制的服务器应用程序中有效。

此外,向 firebase REST API 发出请求仍然是读者的练习。

参考

https://developers.google.com/api-client-library/ruby/auth/service-accounts#authorizingrequests https://developers.google.com/identity/protocols/application-default-credentials#whentouse

【讨论】:

以上是关于以管理员身份使用自定义令牌向 FB DB 发出 REST 请求的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft Graph 和自定义 API 的访问令牌

在哪里覆盖 JWT_EXPIRATION_DELTA 以设置自定义令牌到期时间?

向 Google 进行身份验证时,从 Spring OAuth2 授权服务器发出 JWT 令牌

如何使用自定义策略模式实现 jwt 令牌基础身份验证以在 .net 核心中进行授权?

(自定义)RestAuthenticationProcessingFilter 排序异常

使用发布请求获取身份验证令牌