How To: Simple Firebase REST API server authentication using Ruby
Published 02 December 2016 under software, firebase, real-time database, rubyonrails
Firebase is a set of tools and infrastructure which includes a real-time database. We recently needed to get a Ruby on Rails application talking to a Firebase real-time database over their REST API. Unfortunately, the documentation is somewhat scarce on how to do get authentication to work without using the deprecated auth parameter. The new way seems to be to send an access_token
parameter or Authorization header as part of the request to the API. We are generating the access token using the following:
require 'jwt' credentials = JSON.parse(File.read("credentials.json")) private_key = OpenSSL::PKey::RSA.new credentials["private_key"] def generate_jwt_assertion now_seconds = Time.now.to_i payload = {:iss => credentials["client_email"], :aud => credentials["token_uri"], :iat => now_seconds, :exp => now_seconds+(60*60), # Maximum expiration time is one hour :scope => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/firebase.database' } JWT.encode payload, private_key, "RS256" end def generate_access_token uri = URI.parse(credentials["token_uri"]) https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true req = Net::HTTP::Post.new(uri.path) req['Cache-Control'] = "no-store" req.set_form_data({ grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: generate_jwt_assertion }) resp = JSON.parse(https.request(req).body) resp["access_token"] end
credentials.json
is the file we got from Project settings -> Service Accounts, GENERATE NEW PRIVATE KEY. It's also worth noting we're using the ruby jwt
gem to generate the JSON web token for the assertion. This can be installed using gem install jwt
.
The result from generate_access_token
can then be passed either as a header or a GET parameter in our request to the API. For example, using the Authorization header in a POST request:
def post(path, data) uri = URI.parse("https://#{credentials["project_id"]}.firebaseio.com/#{path}.json") https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true req = Net::HTTP::Post.new(uri.path) req["Authorization"] = "Bearer #{Firebase.get_access_token}" req.body = data.to_json return https.request(req) end
Comments
blog comments powered by Disqus