Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,14 @@ rescue JWT::InvalidIssuerError
end
```

### Required Claims

You can specify claims that must be present for decoding to be successful. JWT::MissingRequiredClaim will be raised if any are missing
```ruby
# Will raise a JWT::ExpiredSignature error if the 'exp' claim is absent
JWT.decode token, hmac_secret, true, { required_claims: ['exp'], algorithm: 'HS256' }
```

### JSON Web Key (JWK)

JWK is a JSON structure representing a cryptographic key. Currently only supports RSA public keys.
Expand Down
1 change: 1 addition & 0 deletions lib/jwt/decode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def find_key(&keyfinder)

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

def validate_segment_count!
Expand Down
3 changes: 2 additions & 1 deletion lib/jwt/default_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ module DefaultOptions
verify_aud: false,
verify_sub: false,
leeway: 0,
algorithms: ['HS256']
algorithms: ['HS256'],
required_claims: []
}.freeze
end
end
1 change: 1 addition & 0 deletions lib/jwt/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class InvalidAudError < DecodeError; end
class InvalidSubError < DecodeError; end
class InvalidJtiError < DecodeError; end
class InvalidPayload < DecodeError; end
class MissingRequiredClaim < DecodeError; end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JWT::MissingRequiredClaim has no descriptive comment

Read more about it here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these error classes have a descriptive comment so I'm not sure I should add one.


class JWKError < DecodeError; end
end
9 changes: 8 additions & 1 deletion lib/jwt/verify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Verify
}.freeze

class << self
%w[verify_aud verify_expiration verify_iat verify_iss verify_jti verify_not_before verify_sub].each do |method_name|
%w[verify_aud verify_expiration verify_iat verify_iss verify_jti verify_not_before verify_sub verify_required_claims].each do |method_name|
define_method method_name do |payload, options|
new(payload, options).send(method_name)
end
Expand Down Expand Up @@ -81,6 +81,13 @@ def verify_sub
raise(JWT::InvalidSubError, "Invalid subject. Expected #{options_sub}, received #{sub || '<none>'}") unless sub.to_s == options_sub.to_s
end

def verify_required_claims
return unless (options_required_claims = @options[:required_claims])
options_required_claims.each do |required_claim|
raise(JWT::MissingRequiredClaim, "Missing required claim #{required_claim}") unless @payload.include?(required_claim)
end
end

private

def global_leeway
Expand Down
14 changes: 14 additions & 0 deletions spec/integration/readme_examples_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,20 @@
end.not_to raise_error
end

it 'required_claims' do
payload = { data: 'test' }

token = JWT.encode payload, hmac_secret, 'HS256'

expect do
JWT.decode token, hmac_secret, true, required_claims: ['exp'], algorithm: 'HS256'
end.to raise_error(JWT::MissingRequiredClaim)

expect do
JWT.decode token, hmac_secret, true, required_claims: ['data'], algorithm: 'HS256'
end.not_to raise_error
end

it 'find_key' do
issuers = %w[My_Awesome_Company1 My_Awesome_Company2]
iss_payload = { data: 'data', iss: issuers.first }
Expand Down
13 changes: 13 additions & 0 deletions spec/jwt/verify_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,17 @@
end
end
end

context '.verify_required_claims(payload, options)' do
it 'must raise JWT::MissingRequiredClaim if a required claim is absent' do
expect do
described_class.verify_required_claims(base_payload, options.merge(required_claims: ['exp']))
end.to raise_error JWT::MissingRequiredClaim
end

it 'must verify the claims if all required claims are present' do
payload = base_payload.merge('exp' => (Time.now.to_i + 5), 'custom_claim' => true)
described_class.verify_required_claims(payload, options.merge(required_claims: ['exp', 'custom_claim']))
end
end
end