class JWT::Decode
Decoding logic for JWT
Public Class Methods
new(jwt, key, verify, options, &keyfinder)
click to toggle source
# File lib/jwt/decode.rb, line 12 def initialize(jwt, key, verify, options, &keyfinder) raise(JWT::DecodeError, 'Nil JSON web token') unless jwt @jwt = jwt @key = key @options = options @segments = jwt.split('.') @verify = verify @signature = '' @keyfinder = keyfinder end
Public Instance Methods
decode_segments()
click to toggle source
# File lib/jwt/decode.rb, line 24 def decode_segments validate_segment_count! if @verify decode_crypto verify_algo set_key verify_signature verify_claims end raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload [payload, header] end
Private Instance Methods
algorithm()
click to toggle source
# File lib/jwt/decode.rb, line 123 def algorithm header['alg'] end
allowed_algorithms()
click to toggle source
# File lib/jwt/decode.rb, line 74 def allowed_algorithms # Order is very important - first check for string keys, next for symbols algos = if @options.key?('algorithm') @options['algorithm'] elsif @options.key?(:algorithm) @options[:algorithm] elsif @options.key?('algorithms') @options['algorithms'] elsif @options.key?(:algorithms) @options[:algorithms] else [] end Array(algos) end
decode_crypto()
click to toggle source
# File lib/jwt/decode.rb, line 119 def decode_crypto @signature = ::JWT::Base64.url_decode(@segments[2] || '') end
find_key() { |header, payload| ... }
click to toggle source
# File lib/jwt/decode.rb, line 90 def find_key(&keyfinder) key = (keyfinder.arity == 2 ? yield(header, payload) : yield(header)) # key can be of type [string, nil, OpenSSL::PKey, Array] return key if key && !Array(key).empty? raise JWT::DecodeError, 'No verification key available' end
header()
click to toggle source
# File lib/jwt/decode.rb, line 127 def header @header ||= parse_and_decode @segments[0] end
none_algorithm?()
click to toggle source
# File lib/jwt/decode.rb, line 115 def none_algorithm? algorithm == 'none' end
options_includes_algo_in_header?()
click to toggle source
# File lib/jwt/decode.rb, line 70 def options_includes_algo_in_header? allowed_algorithms.any? { |alg| alg.casecmp(algorithm).zero? } end
parse_and_decode(segment)
click to toggle source
# File lib/jwt/decode.rb, line 139 def parse_and_decode(segment) JWT::JSON.parse(::JWT::Base64.url_decode(segment)) rescue ::JSON::ParserError raise JWT::DecodeError, 'Invalid segment encoding' end
payload()
click to toggle source
# File lib/jwt/decode.rb, line 131 def payload @payload ||= parse_and_decode @segments[1] end
segment_length()
click to toggle source
# File lib/jwt/decode.rb, line 111 def segment_length @segments.count end
set_key()
click to toggle source
# File lib/jwt/decode.rb, line 58 def set_key @key = find_key(&@keyfinder) if @keyfinder @key = ::JWT::JWK::KeyFinder.new(jwks: @options[:jwks]).key_for(header['kid']) if @options[:jwks] if (x5c_options = @options[:x5c]) @key = X5cKeyFinder.new(x5c_options[:root_certificates], x5c_options[:crls]).from(header['x5c']) end end
signing_input()
click to toggle source
# File lib/jwt/decode.rb, line 135 def signing_input @segments.first(2).join('.') end
validate_segment_count!()
click to toggle source
# File lib/jwt/decode.rb, line 103 def validate_segment_count! return if segment_length == 3 return if !@verify && segment_length == 2 # If no verifying required, the signature is not needed return if segment_length == 2 && none_algorithm? raise(JWT::DecodeError, 'Not enough or too many segments') end
verify_algo()
click to toggle source
# File lib/jwt/decode.rb, line 52 def verify_algo raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms.empty? raise(JWT::IncorrectAlgorithm, 'Token is missing alg header') unless algorithm raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless options_includes_algo_in_header? end
verify_claims()
click to toggle source
# File lib/jwt/decode.rb, line 98 def verify_claims Verify.verify_claims(payload, @options) Verify.verify_required_claims(payload, @options) end
verify_signature()
click to toggle source
# File lib/jwt/decode.rb, line 40 def verify_signature return unless @key || @verify return if none_algorithm? raise JWT::DecodeError, 'No verification key available' unless @key return if Array(@key).any? { |key| verify_signature_for?(key) } raise(JWT::VerificationError, 'Signature verification failed') end
verify_signature_for?(key)
click to toggle source
# File lib/jwt/decode.rb, line 66 def verify_signature_for?(key) Signature.verify(algorithm, key, signing_input, @signature) end