Skip to content

Commit

Permalink
Merge pull request #269 from ab320012/master
Browse files Browse the repository at this point in the history
Fix decode threading issue
  • Loading branch information
excpt authored Jun 7, 2018
2 parents 33fc77a + 7ed2a5a commit 93b02ab
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 68 deletions.
59 changes: 2 additions & 57 deletions lib/jwt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
require 'jwt/default_options'
require 'jwt/encode'
require 'jwt/error'
require 'jwt/signature'
require 'jwt/verify'

# JSON Web Token implementation
#
Expand All @@ -23,60 +21,7 @@ def encode(payload, key, algorithm = 'HS256', header_fields = {})
end

def decode(jwt, key = nil, verify = true, options = {}, &keyfinder)
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt

@jwt = jwt
@key = key
@verify = verify
@options = DEFAULT_OPTIONS.merge(options)
@header,
@payload,
@signature,
@signing_input = Decode.new(jwt, verify).decode_segments
if verify?
verify_signature(&keyfinder)
verify_claims
end

raise(JWT::DecodeError, 'Not enough or too many segments') unless @header && @payload

[@payload, @header]
end

private_class_method

def verify_signature(&keyfinder)
@key = find_key(&keyfinder) if keyfinder

raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms.empty?
raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless options_includes_algo_in_header?

Signature.verify(@header['alg'], @key, @signing_input, @signature)
end

def find_key(&keyfinder)
key = (keyfinder.arity == 2 ? yield(@header, @payload) : yield(@header))
raise JWT::DecodeError, 'No verification key available' unless key
key
end

def allowed_algorithms
if @options.key?(:algorithm)
[@options[:algorithm]]
else
@options[:algorithms] || []
end
end

def verify?
@verify
end

def verify_claims
Verify.verify_claims(@payload, @options)
end

def options_includes_algo_in_header?
allowed_algorithms.include? @header['alg']
decoder = Decode.new(jwt, key, verify, DEFAULT_OPTIONS.merge(options), &keyfinder)
decoder.decode_segments
end
end
58 changes: 47 additions & 11 deletions lib/jwt/decode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

require 'json'

require 'jwt/signature'
require 'jwt/verify'
# JWT::Decode module
module JWT
# Decoding logic for JWT
Expand All @@ -11,23 +13,61 @@ def self.base64url_decode(str)
Base64.decode64(str.tr('-_', '+/'))
end

def initialize(jwt, verify)
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
@header = ''
@payload = ''
@signature = ''
@keyfinder = keyfinder
end

def decode_segments
validate_segment_count
decode_crypto if @verify
return_values
if @verify
decode_crypto
verify_signature
verify_claims
end
raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload
[payload, header]
end

private

def verify_signature
@key = find_key(&@keyfinder) if @keyfinder

raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms.empty?
raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless options_includes_algo_in_header?

Signature.verify(header['alg'], @key, signing_input, @signature)
end

def options_includes_algo_in_header?
allowed_algorithms.include? header['alg']
end

def allowed_algorithms
if @options.key?(:algorithm)
[@options[:algorithm]]
else
@options[:algorithms] || []
end
end

def find_key(&keyfinder)
key = (keyfinder.arity == 2 ? yield(header, payload) : yield(header))
raise JWT::DecodeError, 'No verification key available' unless key
key
end

def verify_claims
Verify.verify_claims(payload, @options)
end

def validate_segment_count
raise(JWT::DecodeError, 'Not enough or too many segments') unless
(@verify && segment_length != 3) ||
Expand All @@ -42,16 +82,12 @@ def decode_crypto
@signature = Decode.base64url_decode(@segments[2])
end

def return_values
[header, payload, @signature, signing_input]
end

def header
parse_and_decode @segments[0]
@header ||= parse_and_decode @segments[0]
end

def payload
parse_and_decode @segments[1]
@payload ||= parse_and_decode @segments[1]
end

def signing_input
Expand Down

0 comments on commit 93b02ab

Please sign in to comment.