class Firebase::FirebaseTokenGenerator
This class handles generating signed authentication tokens for use with Firebase
Constants
- CLAIMS_MAP
- TOKEN_SEP
- TOKEN_VERSION
Public Class Methods
When creating an instance of the generator, you must provide your Firebase
Application Secret
# File lib/firebase_token_generator.rb, line 13 def initialize(secret) if (!secret.is_a?(String)) raise ArgumentError, "FirebaseTokenGenerator: secret must be a string." end @secret = secret end
Public Instance Methods
Returns a signed Firebase
Authentication Token Takes the following arguments:
- auth_data
-
A hash of arbitrary data to be included in the token
- options
-
An optional hash of extra claims that may be included in the token. Allowed values are:
- expires
-
Epoch time after which the token will no longer be valid
- notBefore
-
Epoch time before which the token will not be valid
- admin
-
If set to true, this client will bypass all security rules
- debug
-
If set to true, this client will receive debug information about the security rules
- simulate
-
(internal-only for now) Runs security rules but makes no data changes
Throws ArgumentError if given invalid data or an invalid option Throws RuntimeError if generated token is too long
# File lib/firebase_token_generator.rb, line 32 def create_token(auth_data, options = {}) if (auth_data.nil? or auth_data.empty?) and (options.nil? or options.empty?) raise ArgumentError, "FirebaseTokenGenerator.create_token: data is empty and no options are set. This token will have no effect on Firebase." end validate_auth_data(auth_data, (!options.nil? and options[:admin] == true)) claims = create_options_claims(options) claims[:v] = TOKEN_VERSION claims[:iat] = Time.now.to_i claims[:d] = auth_data token = encode_token(claims) if (token.length > 1024) raise RuntimeError, "FirebaseTokenGenerator.create_token: generated token is too long." end token end
Private Instance Methods
# File lib/firebase_token_generator.rb, line 74 def create_options_claims(options) opts = {} options.each do |key, value| if value.respond_to?(:strftime) then value = value.strftime("%s").to_i end if CLAIMS_MAP.include?(key.to_sym) then opts[CLAIMS_MAP[key.to_sym]] = value else raise ArgumentError, "FirebaseTokenGenerator.create_token: #{key.to_s} is not a valid option" end end opts end
# File lib/firebase_token_generator.rb, line 101 def encode(s) Base64.urlsafe_encode64(s).gsub('=', '') end
# File lib/firebase_token_generator.rb, line 97 def encode_json(obj) encode(JSON.dump(obj)) end
# File lib/firebase_token_generator.rb, line 89 def encode_token(claims) encoded_header = encode_json({:typ => "JWT", :alg => "HS256"}) encoded_claims = encode_json(claims) secure_bits = [encoded_header, encoded_claims].join(TOKEN_SEP) sig = sign(secure_bits) [encoded_header, encoded_claims, sig].join(TOKEN_SEP) end
# File lib/firebase_token_generator.rb, line 105 def sign(to_sign) encode(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, @secret, to_sign)) end
# File lib/firebase_token_generator.rb, line 62 def validate_auth_data(auth_data, is_admin_token) if (!auth_data.nil? && !auth_data.is_a?(Hash)) raise ArgumentError, "FirebaseTokenGenerator.create_token: auth data must be a hash" end contains_uid = (!auth_data.nil? and auth_data.has_key?(:uid)) if ((!contains_uid and !is_admin_token) or (contains_uid and !auth_data[:uid].is_a?(String))) raise ArgumentError, "FirebaseTokenGenerator.create_token: auth data must contain a :uid key that must be a string." elsif (contains_uid and (auth_data[:uid].length > 256)) raise ArgumentError, "FirebaseTokenGenerator.create_token: auth data must contain a :uid key that must not be longer than 256 bytes." end end