diff --git a/lib/jwt/dsl/encode.rb b/lib/jwt/dsl/encode.rb index 511d0cc8..e53957a7 100644 --- a/lib/jwt/dsl/encode.rb +++ b/lib/jwt/dsl/encode.rb @@ -13,6 +13,11 @@ def encode_payload(&block) @encode_payload end + def expiration(value = nil) + @expiration = value unless value.nil? + @expiration + end + def encode!(payload, options = {}) Internals.encode!(payload, options, self) end @@ -29,7 +34,8 @@ def build_options(payload, options, context) key: options[:key] || context.signing_key, encode_payload_proc: context.encode_payload, headers: options[:headers], - algorithm: context.algorithm + algorithm: context.algorithm, + expiration: context.expiration } if opts[:algorithm].is_a?(String) && opts[:key].nil? diff --git a/lib/jwt/encode.rb b/lib/jwt/encode.rb index 789b110e..35ad3520 100644 --- a/lib/jwt/encode.rb +++ b/lib/jwt/encode.rb @@ -29,7 +29,7 @@ def segments attr_reader :headers, :options, :algorithm, :alg def payload - options[:payload] + @payload ||= append_exp(options[:payload]) end def key @@ -84,6 +84,15 @@ def validate_claims! ClaimsValidator.new(payload).validate! end + def append_exp(payload) + return payload unless (expiration = options[:expiration]) + return payload if payload.key?('exp') || payload.key?(:exp) + + payload['exp'] = Time.now.to_i + expiration + + payload + end + class << self def encode(data) Base64.urlsafe_encode64(JWT::JSON.generate(data), padding: false) diff --git a/spec/dsl/encode_spec.rb b/spec/dsl/encode_spec.rb index d3c0a725..dacc0f27 100644 --- a/spec/dsl/encode_spec.rb +++ b/spec/dsl/encode_spec.rb @@ -63,5 +63,18 @@ expect(jwt_class.encode!(payload)).to eq(::JWT.encode(payload, secret, 'HS256')) end end + + context 'when expiration is set on the class and is negative' do + before do + jwt_class.algorithm('HS256') + jwt_class.expiration(-10) + jwt_class.signing_key(secret) + end + + it 'will only generate expired tokens' do + token = jwt_class.encode!(payload) + expect { jwt_class.decode!(token) }.to raise_error(JWT::ExpiredSignature, 'Signature has expired') + end + end end end