Firebase 使用自定义令牌作为管理员向FB DB发出REST请求

Firebase 使用自定义令牌作为管理员向FB DB发出REST请求,firebase,firebase-authentication,Firebase,Firebase Authentication,我正在迁移到新的数据库和3.0客户端libs。我正在更新生成自定义身份验证令牌(在我们的服务器上)的部分,以执行补丁来更新Firebase DB中的资源 这些补丁请求过去由我们的服务器使用admin声明向Firebase发出,基于此: 对于新的DB,我将生成JWT令牌(使用ruby JWT),如下所示: payload = { aud: "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.Ide

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

这些补丁请求过去由我们的服务器使用
admin
声明向Firebase发出,基于此:

对于新的DB,我将生成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 DB请求失败,原因是:
身份验证标头中缺少声明“kid”

在新Firebase中,您需要直接使用服务帐户来创建管理访问凭据。下面是一个Node.js代码段,演示如何对数据库进行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);
  });
});
//key.json是从Firebase控制台下载的服务帐户密钥
var key=require('./key.json');
var google=require('googleapis');
var请求=要求(“请求”);
var数据库https://.firebaseio.com';
var jwtClient=new google.auth.JWT(key.client\u email,null,key.private\u key[
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]);
jwtClient.authorize(函数(错误、令牌){
请求({
url:DATABASE_url+'/.json',
方法:“GET”,
标题:{
“授权”:“持有人”+令牌。访问令牌
}
},函数(err,resp){
控制台日志(分别为主体);
});
});

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

在新的Firebase中,您需要直接使用服务帐户来创建管理访问凭据。下面是一个Node.js代码段,演示如何对数据库进行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);
  });
});
//key.json是从Firebase控制台下载的服务帐户密钥
var key=require('./key.json');
var google=require('googleapis');
var请求=要求(“请求”);
var数据库https://.firebaseio.com';
var jwtClient=new google.auth.JWT(key.client\u email,null,key.private\u key[
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]);
jwtClient.authorize(函数(错误、令牌){
请求({
url:DATABASE_url+'/.json',
方法:“GET”,
标题:{
“授权”:“持有人”+令牌。访问令牌
}
},函数(err,resp){
控制台日志(分别为主体);
});
});

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

下面是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\u APPLICATION\u CREDENTIALS
环境变量设置为服务帐户JSON文件的路径。
auth_client.sub
的值来自此JSON文件中的
client_email

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

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

参考资料


以下是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\u APPLICATION\u CREDENTIALS
环境变量设置为服务帐户JSON文件的路径。
auth_client.sub
的值来自此JSON文件中的
client_email

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

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

参考资料


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