Class: FirebaseIdToken::Signature

Inherits:
Object
  • Object
show all
Defined in:
lib/firebase_id_token/signature.rb

Overview

Deals with verifying if a given Firebase ID Token is signed by one of the Google's x509 certificates that Firebase uses.

Also checks if the resulting JWT payload hash matches with:

  • exp Expiration time
  • iat Issued at time
  • User's Firebase Project ID
  • Non-empty UID

Verifying a Firebase ID Token

Be sure to configure the gem to set your Firebase Project ID cache store.

See the README for a complete guide.

WARNING: Trying to verify a token without any certificate saved in the cache raises a Exceptions::NoCertificatesError.

Examples:

FirebaseIdToken::Signature.verify(thrusty_token)
=> {"iss"=>"https://securetoken.google.com/your-project-id", [...]}

FirebaseIdToken::Signature.verify(fake_token)
=> nil

See Also:

Constant Summary collapse

JWT_DEFAULTS =

Pre-default JWT algorithm parameters as recommended here.

{ algorithm: 'RS256', verify_iat: true }
ISSUER_BASE_URLS =

Issuer base URL of each token type.

{
  id_token: 'https://securetoken.google.com',
  session_cookie: 'https://session.firebase.google.com'
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(jwt_token, raise_error: false, type: :id_token) ⇒ Signature

Loads attributes: :project_ids from Configuration, and :kid, :jwt_token from the related jwt_token.

Parameters:

  • jwt_token (String)

    Firebase ID Token



85
86
87
88
89
90
91
92
# File 'lib/firebase_id_token/signature.rb', line 85

def initialize(jwt_token, raise_error: false, type: :id_token)
  @raise_error = raise_error
  @type = type
  @project_ids = FirebaseIdToken.configuration.project_ids
  @kid = extract_kid(jwt_token)
  @jwt_token = jwt_token
  @firebase_id_token_certificates = FirebaseIdToken.configuration.certificates
end

Instance Attribute Details

#firebase_id_token_certificatesObject

Returns the value of attribute firebase_id_token_certificates.



80
81
82
# File 'lib/firebase_id_token/signature.rb', line 80

def firebase_id_token_certificates
  @firebase_id_token_certificates
end

Class Method Details

.verify(jwt_token, raise_error: false, type: :id_token) ⇒ nil, Hash

Returns the decoded JWT hash payload of the Firebase ID Token if the signature in the token matches with one of the certificates downloaded by Certificates.request, returns nil otherwise.

It will also return nil when it fails in checking if all the required JWT fields are valid, as recommended here by Firebase official documentation.

Note that it will raise a Exceptions::NoCertificatesError if the cache is empty. Ensure to call Certificates.request before, ideally in a background job if you are using Rails.

If you would like this to raise and error, rather than silently failing, you can with the raise_error parameter. Example:

FirebaseIdToken::Signature .verify(token, raise_error: Rails.env.development?)

Use type: :session_cookie to verify a Firebase Session Cookie instead of an ID Token. Session Cookies are issued by https://session.firebase.google.com and signed by a different certificate set. Example:

FirebaseIdToken::Signature.verify(cookie, type: :session_cookie)

Parameters:

  • raise_error (Boolean) (defaults to: false)

    default: false

  • type (Symbol) (defaults to: :id_token)

    :id_token (default) or :session_cookie

Returns:

  • (nil, Hash)


68
69
70
# File 'lib/firebase_id_token/signature.rb', line 68

def self.verify(jwt_token, raise_error: false, type: :id_token)
  new(jwt_token, raise_error: raise_error, type: type).verify
end

.verify!(jwt_token, type: :id_token) ⇒ Hash

Equivalent to .verify(jwt_token, raise_error: true).

Returns:

  • (Hash)

See Also:

  • {Signature{Signature.verify}


76
77
78
# File 'lib/firebase_id_token/signature.rb', line 76

def self.verify!(jwt_token, type: :id_token)
  new(jwt_token, raise_error: true, type: type).verify
end

Instance Method Details

#verifyObject

See Also:



95
96
97
98
99
100
101
102
# File 'lib/firebase_id_token/signature.rb', line 95

def verify
  certificate = firebase_id_token_certificates.find(
    @kid, raise_error: @raise_error, source: @type)
  return unless certificate

  payload = decode_jwt_payload(@jwt_token, certificate.public_key)
  authorize payload
end