I'm migrating to the new database and 3.0 client libs. I'm updating the part which generates a custom auth token (on our server) to do a PATCH
to update a resource in the Firebase DB.
These PATCH requests used to be made by our server to Firebase using admin
claims based on this: https://www.firebase.com/docs/rest/guide/user-auth.htm
For the new DB, I'm generating the JWT token (using ruby-jwt
) like this:
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")
A PATCH
request with this token to the Firebase DB fails with: Missing claim 'kid' in auth header
.
What Are Custom Authentication Tokens? An authentication token is some data, represented as a string or XML, that identifies an entity (user or process), such as an X509 client certificate. Typically, authentication tokens are designed to be used within specific security protocols.
Users of the REST API can authenticate by providing a user ID and password to the REST API login resource with the HTTP POST method. An LTPA token is generated that enables the user to authenticate future requests. This LTPA token has the prefix LtpaToken2 .
In the new Firebase you need to directly use a Service Account to create administrative access credentials. Here is a Node.js snippet that shows how to make a REST call to the Database:
// 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);
});
});
To do the same in Ruby, you might take a look at the googleauth gem for fetching the access token using Service Account credentials.
Here is the equivalent of Michael Bleigh's answer using the ruby googleauth module:
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 = "[email protected]"
token = auth_client.fetch_access_token!
You will also need to set the GOOGLE_APPLICATION_CREDENTIALS
environment variable to the path of your service account JSON file. the value for auth_client.sub
comes from client_email
in this JSON file.
Of course, as above, this is only valid in a server application you control.
Also, making the request to the firebase REST API is still an exercise for the reader.
references
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With