jwt 1.5.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8cd1a9ca017dec28c4984e18003e8ae58aee776c
4
- data.tar.gz: c5fef77f9a8e42d8fa92c060c468be6ee2e3c561
3
+ metadata.gz: c63d3d103ec14f12ea2b51b95ae8f5407dd7ace9
4
+ data.tar.gz: f1de3f1e8ddfb79aa690a1f6d44492c70d037942
5
5
  SHA512:
6
- metadata.gz: c0dc92b0ea35004782c8260f8d2d47c9973a1172f5eb6bef33fe42ae3a2e8341c9264e5fafc7cb62442039409194c3aa6fbd3db78667db75af04ffd26586422f
7
- data.tar.gz: af9967d4c04b332ef8916d3b837e31c20b2e5db8c96531b277286324f29730edbc65eb66401f6db405b22dbd2701895d2579796fab368c26bd1fca58aae30840
6
+ metadata.gz: 3b19fcd5018d17e4277a49abc5787cee37ff3991fc8cbcc97dbb00f50c3878fc08062d97e18e07cdaf5f8f2f09cfbf5a8937e11859ae9b44d90a8d5a20caa021
7
+ data.tar.gz: f9df1adefd0f0d4525567372c8283e72639b2ee67320a893ef03d470bbbd6afd09a65725d3eb3153f8c68e7d40f693c7da3a5ed138ab766a23aa6ebbfe5c62f6
data/.ebert.yml ADDED
@@ -0,0 +1,17 @@
1
+ styleguide: plataformatec/linters
2
+ engines:
3
+ reek:
4
+ enabled: true
5
+ fixme:
6
+ enabled: true
7
+ rubocop:
8
+ enabled: true
9
+ duplication:
10
+ config:
11
+ languages:
12
+ - ruby
13
+ enabled: true
14
+ remark-lint:
15
+ enabled: true
16
+ exclude_paths:
17
+ - spec
data/.reek.yml ADDED
@@ -0,0 +1,40 @@
1
+ ---
2
+ TooManyStatements:
3
+ max_statements: 10
4
+ UncommunicativeMethodName:
5
+ reject:
6
+ - !ruby/regexp /^[a-z]$/
7
+ - !ruby/regexp /[0-9]$/
8
+ UncommunicativeParameterName:
9
+ reject:
10
+ - !ruby/regexp /^.$/
11
+ - !ruby/regexp /[0-9]$/
12
+ - !ruby/regexp /^_/
13
+ UncommunicativeVariableName:
14
+ reject:
15
+ - !ruby/regexp /^.$/
16
+ - !ruby/regexp /[0-9]$/
17
+ UtilityFunction:
18
+ enabled: false
19
+ LongParameterList:
20
+ enabled: false
21
+ DuplicateMethodCall:
22
+ max_calls: 2
23
+ IrresponsibleModule:
24
+ enabled: false
25
+ NestedIterators:
26
+ max_allowed_nesting: 2
27
+ PrimaDonnaMethod:
28
+ enabled: false
29
+ UnusedParameters:
30
+ enabled: false
31
+ FeatureEnvy:
32
+ enabled: false
33
+ ControlParameter:
34
+ enabled: false
35
+ UnusedPrivateMethod:
36
+ enabled: false
37
+ InstanceVariableAssumption:
38
+ exclude:
39
+ - !ruby/regexp /Controller$/
40
+ - !ruby/regexp /Mailer$/s
data/.rubocop.yml CHANGED
@@ -1,2 +1,98 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'bin/**/*'
4
+ - 'db/**/*'
5
+ - 'config/**/*'
6
+ - 'script/**/*'
7
+
8
+ Rails:
9
+ Enabled: true
10
+
11
+ Style/AlignParameters:
12
+ EnforcedStyle: with_fixed_indentation
13
+
14
+ Style/CaseIndentation:
15
+ EnforcedStyle: end
16
+
17
+ Style/AsciiComments:
18
+ Enabled: false
19
+
20
+ Style/IndentHash:
21
+ Enabled: false
22
+
23
+ Style/CollectionMethods:
24
+ Enabled: true
25
+ PreferredMethods:
26
+ inject: 'inject'
27
+
28
+ Style/Documentation:
29
+ Enabled: false
30
+
31
+ Style/BlockDelimiters:
32
+ Exclude:
33
+ - spec/**/*_spec.rb
34
+
35
+ Style/BracesAroundHashParameters:
36
+ Exclude:
37
+ - spec/**/*_spec.rb
38
+
39
+ Style/GuardClause:
40
+ Enabled: false
41
+
42
+ Style/IfUnlessModifier:
43
+ Enabled: false
44
+
45
+ Style/SpaceInsideHashLiteralBraces:
46
+ Enabled: false
47
+
48
+ Style/Lambda:
49
+ Enabled: false
50
+
51
+ Style/RaiseArgs:
52
+ Enabled: false
53
+
54
+ Style/SignalException:
55
+ Enabled: false
56
+
57
+ Metrics/AbcSize:
58
+ Max: 20
59
+
60
+ Metrics/ClassLength:
61
+ Max: 100
62
+
63
+ Metrics/ModuleLength:
64
+ Max: 100
65
+
1
66
  Metrics/LineLength:
2
67
  Enabled: false
68
+
69
+ Metrics/MethodLength:
70
+ Max: 15
71
+
72
+ Style/SingleLineBlockParams:
73
+ Enabled: false
74
+
75
+ Lint/EndAlignment:
76
+ EnforcedStyleAlignWith: variable
77
+
78
+ Style/FormatString:
79
+ Enabled: false
80
+
81
+ Style/MultilineMethodCallIndentation:
82
+ EnforcedStyle: indented
83
+
84
+ Style/MultilineOperationIndentation:
85
+ EnforcedStyle: indented
86
+
87
+ Style/WordArray:
88
+ Enabled: false
89
+
90
+ Style/RedundantSelf:
91
+ Enabled: false
92
+
93
+ Style/AlignHash:
94
+ Enabled: true
95
+ EnforcedLastArgumentHashStyle: always_ignore
96
+
97
+ Style/TrivialAccessors:
98
+ AllowPredicates: true
data/.travis.yml CHANGED
@@ -1,13 +1,14 @@
1
- sudo: false
1
+ sudo: required
2
2
  cache: bundler
3
+ dist: trusty
3
4
  language: ruby
4
5
  rvm:
5
- - 1.9.3
6
- - 2.0.0
7
- - 2.1.0
8
6
  - 2.2.0
9
7
  - 2.3.0
10
- script: "bundle exec rspec"
11
- addons:
12
- code_climate:
13
- repo_token: e87b175db123ab42ca2ca4420abaa13c0dc2085608402b9a25f08a83ca3ba202
8
+ - 2.4.0
9
+ script: "bundle exec rspec && bundle exec codeclimate-test-reporter"
10
+ before_install:
11
+ - sudo add-apt-repository ppa:chris-lea/libsodium -y
12
+ - sudo apt-get update -q
13
+ - sudo apt-get install libsodium-dev -y
14
+ - gem install bundler
data/CHANGELOG.md CHANGED
@@ -1,5 +1,86 @@
1
1
  # Change Log
2
2
 
3
+ ## [v2.0.0](https://github.com/jwt/ruby-jwt/tree/v2.0.0) (2017-09-03)
4
+ [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.0.0.beta1...v2.0.0)
5
+
6
+ **Fixed bugs:**
7
+
8
+ - Support versions outside 2.1 [\#209](https://github.com/jwt/ruby-jwt/issues/209)
9
+ - Verifying expiration without leeway throws exception [\#206](https://github.com/jwt/ruby-jwt/issues/206)
10
+ - Ruby interpreter warning [\#200](https://github.com/jwt/ruby-jwt/issues/200)
11
+ - TypeError: no implicit conversion of String into Integer [\#188](https://github.com/jwt/ruby-jwt/issues/188)
12
+ - Fix JWT.encode\(nil\) [\#203](https://github.com/jwt/ruby-jwt/pull/203) ([tmm1](https://github.com/tmm1))
13
+
14
+ **Closed issues:**
15
+
16
+ - Possibility to disable claim verifications [\#222](https://github.com/jwt/ruby-jwt/issues/222)
17
+ - Proper way to verify Firebase id tokens [\#216](https://github.com/jwt/ruby-jwt/issues/216)
18
+
19
+ **Merged pull requests:**
20
+
21
+ - Skip 'exp' claim validation for array payloads [\#224](https://github.com/jwt/ruby-jwt/pull/224) ([excpt](https://github.com/excpt))
22
+ - Use a default leeway of 0 [\#223](https://github.com/jwt/ruby-jwt/pull/223) ([travisofthenorth](https://github.com/travisofthenorth))
23
+ - Fix reported codesmells [\#221](https://github.com/jwt/ruby-jwt/pull/221) ([excpt](https://github.com/excpt))
24
+ - Add fancy gem version badge [\#220](https://github.com/jwt/ruby-jwt/pull/220) ([excpt](https://github.com/excpt))
25
+ - Add missing dist option to .travis.yml [\#219](https://github.com/jwt/ruby-jwt/pull/219) ([excpt](https://github.com/excpt))
26
+ - Fix ruby version requirements in gemspec file [\#218](https://github.com/jwt/ruby-jwt/pull/218) ([excpt](https://github.com/excpt))
27
+ - Fix a little typo in the readme [\#214](https://github.com/jwt/ruby-jwt/pull/214) ([RyanBrushett](https://github.com/RyanBrushett))
28
+ - Update README.md [\#212](https://github.com/jwt/ruby-jwt/pull/212) ([zuzannast](https://github.com/zuzannast))
29
+ - Fix typo in HS512256 algorithm description [\#211](https://github.com/jwt/ruby-jwt/pull/211) ([ojab](https://github.com/ojab))
30
+ - Allow configuration of multiple acceptable issuers [\#210](https://github.com/jwt/ruby-jwt/pull/210) ([ojab](https://github.com/ojab))
31
+ - Enforce `exp` to be an `Integer` [\#205](https://github.com/jwt/ruby-jwt/pull/205) ([lucasmazza](https://github.com/lucasmazza))
32
+ - ruby 1.9.3 support message upd [\#204](https://github.com/jwt/ruby-jwt/pull/204) ([maokomioko](https://github.com/maokomioko))
33
+ - Guard against partially loaded RbNaCl when failing to load libsodium [\#202](https://github.com/jwt/ruby-jwt/pull/202) ([Dorian](https://github.com/Dorian))
34
+
35
+ ## [v2.0.0.beta1](https://github.com/jwt/ruby-jwt/tree/v2.0.0.beta1) (2017-02-27)
36
+ [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v1.5.6...v2.0.0.beta1)
37
+
38
+ **Implemented enhancements:**
39
+
40
+ - Error with method sign for String [\#171](https://github.com/jwt/ruby-jwt/issues/171)
41
+ - Refactor the encondig code [\#121](https://github.com/jwt/ruby-jwt/issues/121)
42
+ - Refactor [\#196](https://github.com/jwt/ruby-jwt/pull/196) ([EmilioCristalli](https://github.com/EmilioCristalli))
43
+ - Move signature logic to its own module [\#195](https://github.com/jwt/ruby-jwt/pull/195) ([EmilioCristalli](https://github.com/EmilioCristalli))
44
+ - Add options for claim-specific leeway [\#187](https://github.com/jwt/ruby-jwt/pull/187) ([EmilioCristalli](https://github.com/EmilioCristalli))
45
+ - Add user friendly encode error if private key is a String, \#171 [\#176](https://github.com/jwt/ruby-jwt/pull/176) ([xamenrax](https://github.com/xamenrax))
46
+ - Return empty string if signature less than byte\_size \#155 [\#175](https://github.com/jwt/ruby-jwt/pull/175) ([xamenrax](https://github.com/xamenrax))
47
+ - Remove 'typ' optional parameter [\#174](https://github.com/jwt/ruby-jwt/pull/174) ([xamenrax](https://github.com/xamenrax))
48
+ - Pass payload to keyfinder [\#172](https://github.com/jwt/ruby-jwt/pull/172) ([CodeMonkeySteve](https://github.com/CodeMonkeySteve))
49
+ - Use RbNaCl for HMAC if available with fallback to OpenSSL [\#149](https://github.com/jwt/ruby-jwt/pull/149) ([mwpastore](https://github.com/mwpastore))
50
+
51
+ **Fixed bugs:**
52
+
53
+ - ruby-jwt::raw\_to\_asn1: Fails for signatures less than byte\_size [\#155](https://github.com/jwt/ruby-jwt/issues/155)
54
+ - The leeway parameter is applies to all time based verifications [\#129](https://github.com/jwt/ruby-jwt/issues/129)
55
+ - Add options for claim-specific leeway [\#187](https://github.com/jwt/ruby-jwt/pull/187) ([EmilioCristalli](https://github.com/EmilioCristalli))
56
+ - Make algorithm option required to verify signature [\#184](https://github.com/jwt/ruby-jwt/pull/184) ([EmilioCristalli](https://github.com/EmilioCristalli))
57
+ - Validate audience when payload is a scalar and options is an array [\#183](https://github.com/jwt/ruby-jwt/pull/183) ([steti](https://github.com/steti))
58
+
59
+ **Closed issues:**
60
+
61
+ - Different encoded value between servers with same password [\#197](https://github.com/jwt/ruby-jwt/issues/197)
62
+ - Signature is different at each run [\#190](https://github.com/jwt/ruby-jwt/issues/190)
63
+ - Include custom headers with password [\#189](https://github.com/jwt/ruby-jwt/issues/189)
64
+ - can't create token - 'NotImplementedError: Unsupported signing method' [\#186](https://github.com/jwt/ruby-jwt/issues/186)
65
+ - Why jwt depends on json \< 2.0 ? [\#179](https://github.com/jwt/ruby-jwt/issues/179)
66
+ - Cannot verify JWT at all?? [\#177](https://github.com/jwt/ruby-jwt/issues/177)
67
+ - verify\_iss: true is raising JWT::DecodeError instead of JWT::InvalidIssuerError [\#170](https://github.com/jwt/ruby-jwt/issues/170)
68
+
69
+ **Merged pull requests:**
70
+
71
+ - Version bump 2.0.0.beta1 [\#199](https://github.com/jwt/ruby-jwt/pull/199) ([excpt](https://github.com/excpt))
72
+ - Update CHANGELOG.md and minor fixes [\#198](https://github.com/jwt/ruby-jwt/pull/198) ([excpt](https://github.com/excpt))
73
+ - Add Codacy coverage reporter [\#194](https://github.com/jwt/ruby-jwt/pull/194) ([excpt](https://github.com/excpt))
74
+ - Add minimum required ruby version to gemspec [\#193](https://github.com/jwt/ruby-jwt/pull/193) ([excpt](https://github.com/excpt))
75
+ - Code smell fixes [\#192](https://github.com/jwt/ruby-jwt/pull/192) ([excpt](https://github.com/excpt))
76
+ - Version bump to 2.0.0.dev [\#191](https://github.com/jwt/ruby-jwt/pull/191) ([excpt](https://github.com/excpt))
77
+ - Basic encode module refactoring \#121 [\#182](https://github.com/jwt/ruby-jwt/pull/182) ([xamenrax](https://github.com/xamenrax))
78
+ - Fix travis ci build configuration [\#181](https://github.com/jwt/ruby-jwt/pull/181) ([excpt](https://github.com/excpt))
79
+ - Fix travis ci build configuration [\#180](https://github.com/jwt/ruby-jwt/pull/180) ([excpt](https://github.com/excpt))
80
+ - Fix typo in README [\#178](https://github.com/jwt/ruby-jwt/pull/178) ([tomeduarte](https://github.com/tomeduarte))
81
+ - Fix code style [\#173](https://github.com/jwt/ruby-jwt/pull/173) ([excpt](https://github.com/excpt))
82
+ - Fixed a typo in a spec name [\#169](https://github.com/jwt/ruby-jwt/pull/169) ([Mingan](https://github.com/Mingan))
83
+
3
84
  ## [v1.5.6](https://github.com/jwt/ruby-jwt/tree/v1.5.6) (2016-09-19)
4
85
  [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v1.5.5...v1.5.6)
5
86
 
@@ -9,6 +90,7 @@
9
90
 
10
91
  **Merged pull requests:**
11
92
 
93
+ - Update changelog [\#168](https://github.com/jwt/ruby-jwt/pull/168) ([excpt](https://github.com/excpt))
12
94
  - Fix rubocop code smells [\#167](https://github.com/jwt/ruby-jwt/pull/167) ([excpt](https://github.com/excpt))
13
95
 
14
96
  ## [v1.5.5](https://github.com/jwt/ruby-jwt/tree/v1.5.5) (2016-09-16)
@@ -253,7 +335,6 @@
253
335
 
254
336
  **Closed issues:**
255
337
 
256
- - yanking of version 0.1.12 causes issues [\#39](https://github.com/jwt/ruby-jwt/issues/39)
257
338
  - Semantic versioning [\#37](https://github.com/jwt/ruby-jwt/issues/37)
258
339
  - Update gem to get latest changes [\#36](https://github.com/jwt/ruby-jwt/issues/36)
259
340
 
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  source 'https://rubygems.org'
3
2
 
4
3
  gemspec
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # JWT
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/jwt.svg)](https://badge.fury.io/rb/jwt)
3
4
  [![Build Status](https://travis-ci.org/jwt/ruby-jwt.svg)](https://travis-ci.org/jwt/ruby-jwt)
4
5
  [![Code Climate](https://codeclimate.com/github/jwt/ruby-jwt/badges/gpa.svg)](https://codeclimate.com/github/jwt/ruby-jwt)
5
6
  [![Test Coverage](https://codeclimate.com/github/jwt/ruby-jwt/badges/coverage.svg)](https://codeclimate.com/github/jwt/ruby-jwt/coverage)
@@ -7,11 +8,11 @@
7
8
 
8
9
  A pure ruby implementation of the [RFC 7519 OAuth JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) standard.
9
10
 
10
- If you have further questions releated to development or usage, join us: [ruby-jwt google group](https://groups.google.com/forum/#!forum/ruby-jwt).
11
+ If you have further questions related to development or usage, join us: [ruby-jwt google group](https://groups.google.com/forum/#!forum/ruby-jwt).
11
12
 
12
13
  ## Announcements
13
14
 
14
- * Ruby 1.9.3 support will be dropped by December 31st, 2016.
15
+ * Ruby 1.9.3 support was dropped at December 31st, 2016.
15
16
  * Version 1.5.3 yanked. See: [#132](https://github.com/jwt/ruby-jwt/issues/132) and [#133](https://github.com/jwt/ruby-jwt/issues/133)
16
17
 
17
18
  ## Installing
@@ -55,7 +56,7 @@ decoded_token = JWT.decode token, nil, false
55
56
  # Array
56
57
  # [
57
58
  # {"data"=>"test"}, # payload
58
- # {"typ"=>"JWT", "alg"=>"none"} # header
59
+ # {"alg"=>"none"} # header
59
60
  # ]
60
61
  puts decoded_token
61
62
  ```
@@ -63,6 +64,7 @@ puts decoded_token
63
64
  **HMAC** (default: HS256)
64
65
 
65
66
  * HS256 - HMAC using SHA-256 hash algorithm (default)
67
+ * HS512256 - HMAC using SHA-512-256 hash algorithm (only available with RbNaCl; see note below)
66
68
  * HS384 - HMAC using SHA-384 hash algorithm
67
69
  * HS512 - HMAC using SHA-512 hash algorithm
68
70
 
@@ -79,11 +81,17 @@ decoded_token = JWT.decode token, hmac_secret, true, { :algorithm => 'HS256' }
79
81
  # Array
80
82
  # [
81
83
  # {"data"=>"test"}, # payload
82
- # {"typ"=>"JWT", "alg"=>"HS256"} # header
84
+ # {"alg"=>"HS256"} # header
83
85
  # ]
84
86
  puts decoded_token
85
87
  ```
86
88
 
89
+ Note: If [RbNaCl](https://github.com/cryptosphere/rbnacl) is loadable, ruby-jwt will use it for HMAC-SHA256, HMAC-SHA512-256, and HMAC-SHA512. RbNaCl enforces a maximum key size of 32 bytes for these algorithms.
90
+
91
+ [RbNaCl](https://github.com/cryptosphere/rbnacl) requires
92
+ [libsodium](https://github.com/jedisct1/libsodium), it can be installed
93
+ on MacOS with `brew install libsodium`.
94
+
87
95
  **RSA**
88
96
 
89
97
  * RS256 - RSA using SHA-256 hash algorithm
@@ -104,7 +112,7 @@ decoded_token = JWT.decode token, rsa_public, true, { :algorithm => 'RS256' }
104
112
  # Array
105
113
  # [
106
114
  # {"data"=>"test"}, # payload
107
- # {"typ"=>"JWT", "alg"=>"RS256"} # header
115
+ # {"alg"=>"RS256"} # header
108
116
  # ]
109
117
  puts decoded_token
110
118
  ```
@@ -131,7 +139,7 @@ decoded_token = JWT.decode token, ecdsa_public, true, { :algorithm => 'ES256' }
131
139
  # Array
132
140
  # [
133
141
  # {"test"=>"data"}, # payload
134
- # {"typ"=>"JWT", "alg"=>"ES256"} # header
142
+ # {"alg"=>"ES256"} # header
135
143
  # ]
136
144
  puts decoded_token
137
145
  ```
@@ -152,6 +160,38 @@ used. JWT supports these reserved claim names:
152
160
  - 'iat' (Issued At) Claim
153
161
  - 'sub' (Subject) Claim
154
162
 
163
+ ## Add custom header fields
164
+ Ruby-jwt gem supports custom [header fields] (https://tools.ietf.org/html/rfc7519#section-5)
165
+ To add custom header fields you need to pass `header_fields` parameter
166
+
167
+ ```ruby
168
+ token = JWT.encode payload, key, algorithm='HS256', header_fields={}
169
+ ```
170
+
171
+ **Example:**
172
+
173
+ ```ruby
174
+ require 'jwt'
175
+
176
+ payload = {:data => 'test'}
177
+
178
+ # IMPORTANT: set nil as password parameter
179
+ token = JWT.encode payload, nil, 'none', { :typ => "JWT" }
180
+
181
+ # eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.
182
+ puts token
183
+
184
+ # Set password to nil and validation to false otherwise this won't work
185
+ decoded_token = JWT.decode token, nil, false
186
+
187
+ # Array
188
+ # [
189
+ # {"data"=>"test"}, # payload
190
+ # {"typ"=>"JWT", "alg"=>"none"} # header
191
+ # ]
192
+ puts decoded_token
193
+ ```
194
+
155
195
  ### Expiration Time Claim
156
196
 
157
197
  From [Oauth JSON Web Token 4.1.4. "exp" (Expiration Time) Claim](https://tools.ietf.org/html/rfc7519#section-4.1.4):
@@ -186,7 +226,7 @@ token = JWT.encode exp_payload, hmac_secret, 'HS256'
186
226
 
187
227
  begin
188
228
  # add leeway to ensure the token is still accepted
189
- decoded_token = JWT.decode token, hmac_secret, true, { :leeway => leeway, :algorithm => 'HS256' }
229
+ decoded_token = JWT.decode token, hmac_secret, true, { :exp_leeway => leeway, :algorithm => 'HS256' }
190
230
  rescue JWT::ExpiredSignature
191
231
  # Handle expired token, e.g. logout user or deny access
192
232
  end
@@ -226,7 +266,7 @@ token = JWT.encode nbf_payload, hmac_secret, 'HS256'
226
266
 
227
267
  begin
228
268
  # add leeway to ensure the token is valid
229
- decoded_token = JWT.decode token, hmac_secret, true, { :leeway => leeway, :algorithm => 'HS256' }
269
+ decoded_token = JWT.decode token, hmac_secret, true, { :nbf_leeway => leeway, :algorithm => 'HS256' }
230
270
  rescue JWT::ImmatureSignature
231
271
  # Handle invalid token, e.g. logout user or deny access
232
272
  end
@@ -238,6 +278,8 @@ From [Oauth JSON Web Token 4.1.1. "iss" (Issuer) Claim](https://tools.ietf.org/h
238
278
 
239
279
  > The `iss` (issuer) claim identifies the principal that issued the JWT. The processing of this claim is generally application specific. The `iss` value is a case-sensitive string containing a ***StringOrURI*** value. Use of this claim is OPTIONAL.
240
280
 
281
+ You can pass multiple allowed issuers as an Array, verification will pass if one of them matches the `iss` value in the payload.
282
+
241
283
  ```ruby
242
284
  iss = 'My Awesome Company Inc. or https://my.awesome.website/'
243
285
  iss_payload = { :data => 'data', :iss => iss }
@@ -305,6 +347,8 @@ From [Oauth JSON Web Token 4.1.6. "iat" (Issued At) Claim](https://tools.ietf.or
305
347
 
306
348
  > The `iat` (issued at) claim identifies the time at which the JWT was issued. This claim can be used to determine the age of the JWT. Its value MUST be a number containing a ***NumericDate*** value. Use of this claim is OPTIONAL.
307
349
 
350
+ **Handle Issued At Claim**
351
+
308
352
  ```ruby
309
353
  iat = Time.now.to_i
310
354
  iat_payload = { :data => 'data', :iat => iat }
@@ -319,6 +363,25 @@ rescue JWT::InvalidIatError
319
363
  end
320
364
  ```
321
365
 
366
+ **Adding Leeway**
367
+
368
+ ```ruby
369
+ iat = Time.now.to_i + 10
370
+ leeway = 30 # seconds
371
+
372
+ iat_payload = { :data => 'data', :iat => iat }
373
+
374
+ # build token issued in the future
375
+ token = JWT.encode iat_payload, hmac_secret, 'HS256'
376
+
377
+ begin
378
+ # add leeway to ensure the token is accepted
379
+ decoded_token = JWT.decode token, hmac_secret, true, { :iat_leeway => leeway, :verify_iat => true, :algorithm => 'HS256' }
380
+ rescue JWT::InvalidIatError
381
+ # Handle invalid token, e.g. logout user or deny access
382
+ end
383
+ ```
384
+
322
385
  ### Subject Claim
323
386
 
324
387
  From [Oauth JSON Web Token 4.1.2. "sub" (Subject) Claim](https://tools.ietf.org/html/rfc7519#section-4.1.2):
data/lib/jwt/decode.rb CHANGED
@@ -1,57 +1,49 @@
1
1
  # frozen_string_literal: true
2
- require 'jwt/json'
3
- require 'jwt/verify'
2
+
3
+ require 'json'
4
4
 
5
5
  # JWT::Decode module
6
6
  module JWT
7
- extend JWT::Json
8
-
9
7
  # Decoding logic for JWT
10
8
  class Decode
11
9
  attr_reader :header, :payload, :signature
12
10
 
13
- def initialize(jwt, key, verify, options, &keyfinder)
11
+ def self.base64url_decode(str)
12
+ str += '=' * (4 - str.length.modulo(4))
13
+ Base64.decode64(str.tr('-_', '+/'))
14
+ end
15
+
16
+ def initialize(jwt, verify)
14
17
  @jwt = jwt
15
- @key = key
16
18
  @verify = verify
17
- @options = options
18
- @keyfinder = keyfinder
19
+ @header = ''
20
+ @payload = ''
21
+ @signature = ''
19
22
  end
20
23
 
21
24
  def decode_segments
22
- header_segment, payload_segment, crypto_segment = raw_segments(@jwt, @verify)
25
+ header_segment, payload_segment, crypto_segment = raw_segments
23
26
  @header, @payload = decode_header_and_payload(header_segment, payload_segment)
24
27
  @signature = Decode.base64url_decode(crypto_segment.to_s) if @verify
25
28
  signing_input = [header_segment, payload_segment].join('.')
26
29
  [@header, @payload, @signature, signing_input]
27
30
  end
28
31
 
29
- def raw_segments(jwt, verify)
30
- segments = jwt.split('.')
31
- required_num_segments = verify ? [3] : [2, 3]
32
+ private
33
+
34
+ def raw_segments
35
+ segments = @jwt.split('.')
36
+ required_num_segments = @verify ? [3] : [2, 3]
32
37
  raise(JWT::DecodeError, 'Not enough or too many segments') unless required_num_segments.include? segments.length
33
38
  segments
34
39
  end
35
- private :raw_segments
36
40
 
37
41
  def decode_header_and_payload(header_segment, payload_segment)
38
- header = JWT.decode_json(Decode.base64url_decode(header_segment))
39
- payload = JWT.decode_json(Decode.base64url_decode(payload_segment))
42
+ header = JSON.parse(Decode.base64url_decode(header_segment))
43
+ payload = JSON.parse(Decode.base64url_decode(payload_segment))
40
44
  [header, payload]
41
- end
42
- private :decode_header_and_payload
43
-
44
- def self.base64url_decode(str)
45
- str += '=' * (4 - str.length.modulo(4))
46
- Base64.decode64(str.tr('-_', '+/'))
47
- end
48
-
49
- def verify
50
- @options.each do |key, val|
51
- next unless key.to_s =~ /verify/
52
-
53
- Verify.send(key, payload, @options) if val
54
- end
45
+ rescue JSON::ParserError
46
+ raise JWT::DecodeError, 'Invalid segment encoding'
55
47
  end
56
48
  end
57
49
  end
@@ -0,0 +1,14 @@
1
+ module JWT
2
+ module DefaultOptions
3
+ DEFAULT_OPTIONS = {
4
+ verify_expiration: true,
5
+ verify_not_before: true,
6
+ verify_iss: false,
7
+ verify_iat: false,
8
+ verify_jti: false,
9
+ verify_aud: false,
10
+ verify_sub: false,
11
+ leeway: 0
12
+ }.freeze
13
+ end
14
+ end
data/lib/jwt/encode.rb ADDED
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ # JWT::Encode module
6
+ module JWT
7
+ # Encoding logic for JWT
8
+ class Encode
9
+ attr_reader :payload, :key, :algorithm, :header_fields, :segments
10
+
11
+ def self.base64url_encode(str)
12
+ Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
13
+ end
14
+
15
+ def initialize(payload, key, algorithm, header_fields)
16
+ @payload = payload
17
+ @key = key
18
+ @algorithm = algorithm
19
+ @header_fields = header_fields
20
+ @segments = encode_segments
21
+ end
22
+
23
+ private
24
+
25
+ def encoded_header
26
+ header = { 'alg' => @algorithm }.merge(@header_fields)
27
+ Encode.base64url_encode(JSON.generate(header))
28
+ end
29
+
30
+ def encoded_payload
31
+ raise InvalidPayload, 'exp claim must be an integer' if @payload && !@payload.is_a?(Array) && @payload.key?('exp') && !@payload['exp'].is_a?(Integer)
32
+ Encode.base64url_encode(JSON.generate(@payload))
33
+ end
34
+
35
+ def encoded_signature(signing_input)
36
+ if @algorithm == 'none'
37
+ ''
38
+ else
39
+ signature = JWT::Signature.sign(@algorithm, signing_input, @key)
40
+ Encode.base64url_encode(signature)
41
+ end
42
+ end
43
+
44
+ def encode_segments
45
+ header = encoded_header
46
+ payload = encoded_payload
47
+ signature = encoded_signature([header, payload].join('.'))
48
+ [header, payload, signature].join('.')
49
+ end
50
+ end
51
+ end
data/lib/jwt/error.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module JWT
4
+ class EncodeError < StandardError; end
3
5
  class DecodeError < StandardError; end
4
6
  class VerificationError < DecodeError; end
5
7
  class ExpiredSignature < DecodeError; end