class Firebase::Admin::Auth::JWTVerifier

Base class for verifying Firebase JWTs.

Public Class Methods

new(app, certificates_url) click to toggle source

Initializes a new verifier.

@param [Firebase::Admin::App] app

The Firebase app to verify tokens for.

@param [String] certificates_url

The url to load public key certificates used during token verification.
# File lib/firebase/admin/auth/token_verifier.rb, line 15
def initialize(app, certificates_url)
  @project_id = app.project_id
  @certificates = CertificatesFetcher.new(certificates_url)
end

Public Instance Methods

expired_error() click to toggle source
# File lib/firebase/admin/auth/token_verifier.rb, line 46
def expired_error
  raise NotImplementedError
end
invalid_error() click to toggle source
# File lib/firebase/admin/auth/token_verifier.rb, line 42
def invalid_error
  raise NotImplementedError
end
issuer() click to toggle source

Override in subclasses to set the issuer

# File lib/firebase/admin/auth/token_verifier.rb, line 38
def issuer
  raise NotImplementedError
end
verify(token, is_emulator: false) click to toggle source

Verifies a Firebase ID token.

@param [String] token A Firebase JWT ID token. @param [Boolean] is_emulator skips signature verification if true. @return [Hash] the verified claims.

# File lib/firebase/admin/auth/token_verifier.rb, line 25
def verify(token, is_emulator: false)
  payload = decode(token, is_emulator).first
  sub = payload["sub"]
  raise JWT::InvalidSubError, "Invalid subject." unless sub.is_a?(String) && !sub.empty?
  payload["uid"] = sub
  payload
rescue JWT::ExpiredSignature => e
  raise expired_error, e.message
rescue JWT::DecodeError => e
  raise invalid_error, e.message
end

Private Instance Methods

decode(token, is_emulator) click to toggle source
# File lib/firebase/admin/auth/token_verifier.rb, line 71
def decode(token, is_emulator)
  return decode_unsigned(token) if is_emulator
  JWT.decode(token, nil, true, decode_options) do |header|
    find_key(header)
  end
end
decode_options() click to toggle source
# File lib/firebase/admin/auth/token_verifier.rb, line 52
def decode_options
  {
    iss: issuer,
    aud: @project_id,
    algorithm: "RS256",
    verify_iat: true,
    verify_iss: true,
    verify_aud: true
  }
end
decode_unsigned(token) click to toggle source
# File lib/firebase/admin/auth/token_verifier.rb, line 78
def decode_unsigned(token)
  raise InvalidTokenError, "token must not be nil" unless token
  raise InvalidTokenError, "token must be a string" unless token.is_a?(String)
  raise InvalidTokenError, "The auth emulator only accepts unsigned ID tokens." if token.split(".").length == 3
  options = decode_options.merge({algorithm: "none"})
  JWT.decode(token, nil, false, options)
end
find_key(header) click to toggle source
# File lib/firebase/admin/auth/token_verifier.rb, line 63
def find_key(header)
  return nil unless header["kid"].is_a?(String)
  certificate = @certificates.fetch_certificates![header["kid"]]
  OpenSSL::X509::Certificate.new(certificate).public_key unless certificate.nil?
rescue OpenSSL::X509::CertificateError => e
  raise InvalidCertificateError, e.message
end