jwt 1.5.2 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +13 -5
  2. data/.codeclimate.yml +20 -0
  3. data/.gitignore +6 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +2 -0
  6. data/.travis.yml +13 -0
  7. data/Gemfile +4 -0
  8. data/README.md +29 -11
  9. data/Rakefile +1 -18
  10. data/lib/jwt.rb +19 -75
  11. data/lib/jwt/decode.rb +56 -0
  12. data/lib/jwt/error.rb +12 -0
  13. data/lib/jwt/json.rb +9 -25
  14. data/lib/jwt/verify.rb +98 -0
  15. data/lib/jwt/version.rb +23 -0
  16. data/ruby-jwt.gemspec +29 -0
  17. data/spec/fixtures/certs/ec256-private.pem +8 -0
  18. data/spec/fixtures/certs/ec256-public.pem +4 -0
  19. data/spec/fixtures/certs/ec256-wrong-private.pem +8 -0
  20. data/spec/fixtures/certs/ec256-wrong-public.pem +4 -0
  21. data/spec/fixtures/certs/ec384-private.pem +9 -0
  22. data/spec/fixtures/certs/ec384-public.pem +5 -0
  23. data/spec/fixtures/certs/ec384-wrong-private.pem +9 -0
  24. data/spec/fixtures/certs/ec384-wrong-public.pem +5 -0
  25. data/spec/fixtures/certs/ec512-private.pem +10 -0
  26. data/spec/fixtures/certs/ec512-public.pem +6 -0
  27. data/spec/fixtures/certs/ec512-wrong-private.pem +10 -0
  28. data/spec/fixtures/certs/ec512-wrong-public.pem +6 -0
  29. data/spec/fixtures/certs/rsa-1024-private.pem +15 -0
  30. data/spec/fixtures/certs/rsa-1024-public.pem +6 -0
  31. data/spec/fixtures/certs/rsa-2048-private.pem +27 -0
  32. data/spec/fixtures/certs/rsa-2048-public.pem +9 -0
  33. data/spec/fixtures/certs/rsa-2048-wrong-private.pem +27 -0
  34. data/spec/fixtures/certs/rsa-2048-wrong-public.pem +9 -0
  35. data/spec/fixtures/certs/rsa-4096-private.pem +51 -0
  36. data/spec/fixtures/certs/rsa-4096-public.pem +14 -0
  37. data/spec/jwt/verify_spec.rb +175 -0
  38. data/spec/jwt_spec.rb +1 -181
  39. data/spec/spec_helper.rb +2 -3
  40. metadata +145 -28
  41. data/jwt.gemspec +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6ff1115eaca264c9790778ded501361f414caa62
4
- data.tar.gz: 9a42e93dc852e9456dbf793a34bd922f38f541c7
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDM3ZjQ5OWVjMGQ3NDYxZWRmZjAxNTQzZmU5YjlhODg4YzcwY2QzMg==
5
+ data.tar.gz: !binary |-
6
+ YmM3YWU5NTkxNDEzOGQyMTAzMTIyYzVmNWNhY2ZlMWU2NTFlZjliNQ==
5
7
  SHA512:
6
- metadata.gz: 590c037185cc14d2f1dff665960131b6960a601a82448f0330abfd5378f742d038a72dec7bc7bfe15d7e5f4ddee9733f4d3aff9e5c3141c1b950aa0ad61b52fa
7
- data.tar.gz: dce378411b1e8f3687afa6fa1cbe75dc60990e7df93b04da9ad71c9529d4a856e4dab215ec568b819b9fea626d150002a067fe1d0ed38680d260f7701337ac0a
8
+ metadata.gz: !binary |-
9
+ NzA3NWQ4ZjQ4OWEyNTY5ZjE5NGYzMjBhZDkzMmZhOTdmNzcwMmMxNWI5MmYz
10
+ N2E3MmE5NmQ1ZjlhZTU2ZDc3NDYxYzIxZjhkMjJjOGE1NDI5MDI4MmVmN2Fi
11
+ ZGExYWMzOGI3ZDAxNWE2NzdhOWRjNjkzZjAxMjRmMGM0NTIwZDU=
12
+ data.tar.gz: !binary |-
13
+ OGQxM2IyM2E1ZTUzM2QzZjBlMmZiYzBiMGU4OGM5YjI5NTU0YjA2ZWQ3MDY3
14
+ MjQ0ZDMxNTEzMWE0NzUzYjAxOGQ2MTAwZTFiMmU5YmYzZDFjYTVhNTdhOGVm
15
+ N2Q3Mjk0ODMxYWI3NDg3M2IwYzA5MmMwYTgzNzhjM2U5YTJkODI=
@@ -0,0 +1,20 @@
1
+ engines:
2
+ rubocop:
3
+ enabled: true
4
+ golint:
5
+ enabled: false
6
+ gofmt:
7
+ enabled: false
8
+ eslint:
9
+ enabled: false
10
+ csslint:
11
+ enabled: false
12
+
13
+ ratings:
14
+ paths:
15
+ - lib/**
16
+ - "**.rb"
17
+
18
+ exclude_paths:
19
+ - spec/**/*
20
+ - vendor/**/*
@@ -0,0 +1,6 @@
1
+ .idea/
2
+ jwt.gemspec
3
+ pkg
4
+ Gemfile.lock
5
+ coverage/
6
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format d
@@ -0,0 +1,2 @@
1
+ Metrics/LineLength:
2
+ Enabled: false
@@ -0,0 +1,13 @@
1
+ sudo: false
2
+ cache: bundler
3
+ language: ruby
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - 2.2.0
9
+ - 2.3.0
10
+ script: "bundle exec rspec"
11
+ addons:
12
+ code_climate:
13
+ repo_token: e87b175db123ab42ca2ca4420abaa13c0dc2085608402b9a25f08a83ca3ba202
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ source 'https://rubygems.org'
3
+
4
+ gemspec
data/README.md CHANGED
@@ -1,14 +1,33 @@
1
1
  # JWT
2
- A Ruby implementation of [JSON Web Token](https://tools.ietf.org/html/rfc7519).
2
+
3
+ [![Build Status](https://travis-ci.org/jwt/ruby-jwt.svg)](https://travis-ci.org/jwt/ruby-jwt)
4
+ [![Code Climate](https://codeclimate.com/github/jwt/ruby-jwt/badges/gpa.svg)](https://codeclimate.com/github/jwt/ruby-jwt)
5
+ [![Test Coverage](https://codeclimate.com/github/jwt/ruby-jwt/badges/coverage.svg)](https://codeclimate.com/github/jwt/ruby-jwt/coverage)
6
+ [![Issue Count](https://codeclimate.com/github/jwt/ruby-jwt/badges/issue_count.svg)](https://codeclimate.com/github/jwt/ruby-jwt)
7
+
8
+ A pure ruby implementation of the [RFC 7519 OAuth JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) standard.
3
9
 
4
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).
5
11
 
12
+ ## Announcements
13
+
14
+ * Ruby 1.9.3 support will be dropped by December 31st, 2016.
15
+ * Version 1.5.3 yanked. See: #132 and #133
16
+
6
17
  ## Installing
7
18
 
19
+ ### Using Rubygems:
8
20
  ```bash
9
21
  sudo gem install jwt
10
22
  ```
11
23
 
24
+ ### Using Bundler:
25
+ Add the following to your Gemfile
26
+ ```
27
+ gem 'jwt'
28
+ ```
29
+ And run `bundle install`
30
+
12
31
  ## Algorithms and Usage
13
32
 
14
33
  The JWT spec supports NONE, HMAC, RSASSA, ECDSA and RSASSA-PSS algorithms for cryptographic signing. Currently the jwt gem supports NONE, HMAC, RSASSA and ECDSA. If you are using cryptographic signing, you need to specify the algorithm in the options hash whenever you call JWT.decode to ensure that an attacker [cannot bypass the algorithm verification step](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/).
@@ -227,7 +246,7 @@ token = JWT.encode iss_payload, hmac_secret, 'HS256'
227
246
 
228
247
  begin
229
248
  # Add iss to the validation to check if the token has been manipulated
230
- decoded_token = JWT.decode token, hmac_secret, true, { 'iss' => iss, :verify_iss => true, :algorithm => 'HS256' }
249
+ decoded_token = JWT.decode token, hmac_secret, true, { :iss => iss, :verify_iss => true, :algorithm => 'HS256' }
231
250
  rescue JWT::InvalidIssuerError
232
251
  # Handle invalid token, e.g. logout user or deny access
233
252
  end
@@ -247,7 +266,7 @@ token = JWT.encode aud_payload, hmac_secret, 'HS256'
247
266
 
248
267
  begin
249
268
  # Add aud to the validation to check if the token has been manipulated
250
- decoded_token = JWT.decode token, hmac_secret, true, { 'aud' => aud, :verify_aud => true, :algorithm => 'HS256' }
269
+ decoded_token = JWT.decode token, hmac_secret, true, { :aud => aud, :verify_aud => true, :algorithm => 'HS256' }
251
270
  rescue JWT::InvalidAudError
252
271
  # Handle invalid token, e.g. logout user or deny access
253
272
  puts 'Audience Error'
@@ -261,8 +280,6 @@ From [Oauth JSON Web Token 4.1.7. "jti" (JWT ID) Claim](https://tools.ietf.org/h
261
280
  > The `jti` (JWT ID) claim provides a unique identifier for the JWT. The identifier value MUST be assigned in a manner that ensures that there is a negligible probability that the same value will be accidentally assigned to a different data object; if the application uses multiple issuers, collisions MUST be prevented among values produced by different issuers as well. The `jti` claim can be used to prevent the JWT from being replayed. The `jti` value is a case-sensitive string. Use of this claim is OPTIONAL.
262
281
 
263
282
  ```ruby
264
- # in order to use JTI you have to add iat
265
- iat = Time.now.to_i
266
283
  # Use the secret and iat to create a unique key per request to prevent replay attacks
267
284
  jti_raw = [hmac_secret, iat].join(':').to_s
268
285
  jti = Digest::MD5.hexdigest(jti_raw)
@@ -271,9 +288,10 @@ jti_payload = { :data => 'data', :iat => iat, :jti => jti }
271
288
  token = JWT.encode jti_payload, hmac_secret, 'HS256'
272
289
 
273
290
  begin
274
- # Add jti and iat to the validation to check if the token has been manipulated
275
- decoded_token = JWT.decode token, hmac_secret, true, { 'jti' => jti, :verify_jti => true, :algorithm => 'HS256' }
276
- # Check if the JTI has already been used
291
+ # If :verify_jti is true, validation will pass if a JTI is present
292
+ #decoded_token = JWT.decode token, hmac_secret, true, { :verify_jti => true, :algorithm => 'HS256' }
293
+ # Alternatively, pass a proc with your own code to check if the JTI has already been used
294
+ decoded_token = JWT.decode token, hmac_secret, true, { :verify_jti => proc { |jti| my_validation_method(jti) }, :algorithm => 'HS256' }
277
295
  rescue JWT::InvalidJtiError
278
296
  # Handle invalid token, e.g. logout user or deny access
279
297
  puts 'Error'
@@ -323,16 +341,16 @@ end
323
341
 
324
342
  # Development and Tests
325
343
 
326
- We depend on [Echoe](http://rubygems.org/gems/echoe) for defining gemspec and performing releases to rubygems.org, which can be done with
344
+ We depend on [Bundler](http://rubygems.org/gems/bundler) for defining gemspec and performing releases to rubygems.org, which can be done with
327
345
 
328
346
  ```bash
329
347
  rake release
330
348
  ```
331
349
 
332
- The tests are written with rspec. Given you have rake and rspec, you can run tests with
350
+ The tests are written with rspec. Given you have installed the dependencies via bundler, you can run tests with
333
351
 
334
352
  ```bash
335
- rake test
353
+ bundle exec rspec
336
354
  ```
337
355
 
338
356
  **If you want a release cut with your PR, please include a version bump according to [Semantic Versioning](http://semver.org/)**
data/Rakefile CHANGED
@@ -1,18 +1 @@
1
- # encoding: utf-8
2
- require 'rubygems'
3
- require 'rake'
4
- require 'echoe'
5
-
6
- Echoe.new('jwt', '1.5.2') do |p|
7
- p.description = 'JSON Web Token implementation in Ruby'
8
- p.url = 'http://github.com/progrium/ruby-jwt'
9
- p.author = 'Jeff Lindsay'
10
- p.email = 'progrium@gmail.com'
11
- p.ignore_pattern = ['tmp/*']
12
- p.development_dependencies = ['echoe >=4.6.3']
13
- p.licenses = 'MIT'
14
- end
15
-
16
- task :test do
17
- sh 'rspec spec/jwt_spec.rb'
18
- end
1
+ require 'bundler/gem_tasks'
data/lib/jwt.rb CHANGED
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
2
-
3
1
  require 'base64'
4
2
  require 'openssl'
3
+ require 'jwt/decode'
4
+ require 'jwt/error'
5
5
  require 'jwt/json'
6
6
 
7
7
  # JSON Web Token implementation
@@ -9,16 +9,6 @@ require 'jwt/json'
9
9
  # Should be up to date with the latest spec:
10
10
  # https://tools.ietf.org/html/rfc7519#section-4.1.5
11
11
  module JWT
12
- class DecodeError < StandardError; end
13
- class VerificationError < DecodeError; end
14
- class ExpiredSignature < DecodeError; end
15
- class IncorrectAlgorithm < DecodeError; end
16
- class ImmatureSignature < DecodeError; end
17
- class InvalidIssuerError < DecodeError; end
18
- class InvalidIatError < DecodeError; end
19
- class InvalidAudError < DecodeError; end
20
- class InvalidSubError < DecodeError; end
21
- class InvalidJtiError < DecodeError; end
22
12
  extend JWT::Json
23
13
 
24
14
  NAMED_CURVES = {
@@ -73,11 +63,6 @@ module JWT
73
63
  OpenSSL::HMAC.digest(OpenSSL::Digest.new(algorithm.sub('HS', 'sha')), key, msg)
74
64
  end
75
65
 
76
- def base64url_decode(str)
77
- str += '=' * (4 - str.length.modulo(4))
78
- Base64.decode64(str.tr('-_', '+/'))
79
- end
80
-
81
66
  def base64url_encode(str)
82
67
  Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
83
68
  end
@@ -109,34 +94,10 @@ module JWT
109
94
  segments.join('.')
110
95
  end
111
96
 
112
- def raw_segments(jwt, verify = true)
113
- segments = jwt.split('.')
114
- required_num_segments = verify ? [3] : [2, 3]
115
- fail(JWT::DecodeError, 'Not enough or too many segments') unless required_num_segments.include? segments.length
116
- segments
117
- end
118
-
119
- def decode_header_and_payload(header_segment, payload_segment)
120
- header = decode_json(base64url_decode(header_segment))
121
- payload = decode_json(base64url_decode(payload_segment))
122
- [header, payload]
123
- end
124
-
125
- def decoded_segments(jwt, verify = true)
126
- header_segment, payload_segment, crypto_segment = raw_segments(jwt, verify)
127
- header, payload = decode_header_and_payload(header_segment, payload_segment)
128
- signature = base64url_decode(crypto_segment.to_s) if verify
129
- signing_input = [header_segment, payload_segment].join('.')
130
- [header, payload, signature, signing_input]
131
- end
132
-
133
- def decode(jwt, key = nil, verify = true, options = {}, &keyfinder)
97
+ def decode(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
134
98
  fail(JWT::DecodeError, 'Nil JSON web token') unless jwt
135
99
 
136
- header, payload, signature, signing_input = decoded_segments(jwt, verify)
137
- fail(JWT::DecodeError, 'Not enough or too many segments') unless header && payload
138
-
139
- default_options = {
100
+ options = {
140
101
  verify_expiration: true,
141
102
  verify_not_before: true,
142
103
  verify_iss: false,
@@ -147,43 +108,22 @@ module JWT
147
108
  leeway: 0
148
109
  }
149
110
 
150
- options = default_options.merge(options)
111
+ merged_options = options.merge(custom_options)
112
+
113
+ decoder = Decode.new jwt, key, verify, merged_options, &keyfinder
114
+ header, payload, signature, signing_input = decoder.decode_segments
115
+ decoder.verify
116
+
117
+ fail(JWT::DecodeError, 'Not enough or too many segments') unless header && payload
151
118
 
152
119
  if verify
153
120
  algo, key = signature_algorithm_and_key(header, key, &keyfinder)
154
- if options[:algorithm] && algo != options[:algorithm]
121
+ if merged_options[:algorithm] && algo != merged_options[:algorithm]
155
122
  fail JWT::IncorrectAlgorithm, 'Expected a different algorithm'
156
123
  end
157
124
  verify_signature(algo, key, signing_input, signature)
158
125
  end
159
126
 
160
- if options[:verify_expiration] && payload.include?('exp')
161
- fail(JWT::ExpiredSignature, 'Signature has expired') unless payload['exp'].to_i > (Time.now.to_i - options[:leeway])
162
- end
163
- if options[:verify_not_before] && payload.include?('nbf')
164
- fail(JWT::ImmatureSignature, 'Signature nbf has not been reached') unless payload['nbf'].to_i <= (Time.now.to_i + options[:leeway])
165
- end
166
- if options[:verify_iss] && options[:iss]
167
- fail(JWT::InvalidIssuerError, "Invalid issuer. Expected #{options[:iss]}, received #{payload['iss'] || '<none>'}") unless payload['iss'].to_s == options[:iss].to_s
168
- end
169
- if options[:verify_iat] && payload.include?('iat')
170
- fail(JWT::InvalidIatError, 'Invalid iat') unless payload['iat'].is_a?(Integer) && payload['iat'].to_i <= (Time.now.to_i + options[:leeway])
171
- end
172
- if options[:verify_aud] && options[:aud]
173
- if payload[:aud].is_a?(Array)
174
- fail(JWT::InvalidAudError, 'Invalid audience') unless payload['aud'].include?(options[:aud].to_s)
175
- else
176
- fail(JWT::InvalidAudError, "Invalid audience. Expected #{options[:aud]}, received #{payload['aud'] || '<none>'}") unless payload['aud'].to_s == options[:aud].to_s
177
- end
178
- end
179
- if options[:verify_sub] && options.include?(:sub)
180
- fail(JWT::InvalidSubError, "Invalid subject. Expected #{options[:sub]}, received #{payload['sub'] || '<none>'}") unless payload['sub'].to_s == options[:sub].to_s
181
- end
182
- if options[:verify_jti] && payload.include?('jti')
183
- fail(JWT::InvalidJtiError, 'need iat for verify jwt id') unless payload.include?('iat')
184
- fail(JWT::InvalidJtiError, 'Not a uniq jwt id') unless options[:jti].to_s == Digest::MD5.hexdigest("#{key}:#{payload['iat']}")
185
- end
186
-
187
127
  [payload, header]
188
128
  end
189
129
 
@@ -194,11 +134,11 @@ module JWT
194
134
 
195
135
  def verify_signature(algo, key, signing_input, signature)
196
136
  if %w(HS256 HS384 HS512).include?(algo)
197
- fail(JWT::VerificationError, 'Signature verification raiseed') unless secure_compare(signature, sign_hmac(algo, signing_input, key))
137
+ fail(JWT::VerificationError, 'Signature verification raised') unless secure_compare(signature, sign_hmac(algo, signing_input, key))
198
138
  elsif %w(RS256 RS384 RS512).include?(algo)
199
- fail(JWT::VerificationError, 'Signature verification raiseed') unless verify_rsa(algo, key, signing_input, signature)
139
+ fail(JWT::VerificationError, 'Signature verification raised') unless verify_rsa(algo, key, signing_input, signature)
200
140
  elsif %w(ES256 ES384 ES512).include?(algo)
201
- fail(JWT::VerificationError, 'Signature verification raiseed') unless verify_ecdsa(algo, key, signing_input, signature)
141
+ fail(JWT::VerificationError, 'Signature verification raised') unless verify_ecdsa(algo, key, signing_input, signature)
202
142
  else
203
143
  fail JWT::VerificationError, 'Algorithm not supported'
204
144
  end
@@ -230,4 +170,8 @@ module JWT
230
170
  byte_size = (public_key.group.degree + 7) / 8
231
171
  OpenSSL::ASN1.decode(signature).value.map { |value| value.value.to_s(2).rjust(byte_size, "\x00") }.join
232
172
  end
173
+
174
+ def base64url_decode(str)
175
+ Decode.base64url_decode(str)
176
+ end
233
177
  end
@@ -0,0 +1,56 @@
1
+ require 'jwt/json'
2
+ require 'jwt/verify'
3
+
4
+ # JWT::Decode module
5
+ module JWT
6
+ extend JWT::Json
7
+
8
+ # Decoding logic for JWT
9
+ class Decode
10
+ attr_reader :header, :payload, :signature
11
+
12
+ def initialize(jwt, key, verify, options, &keyfinder)
13
+ @jwt = jwt
14
+ @key = key
15
+ @verify = verify
16
+ @options = options
17
+ @keyfinder = keyfinder
18
+ end
19
+
20
+ def decode_segments
21
+ header_segment, payload_segment, crypto_segment = raw_segments(@jwt, @verify)
22
+ @header, @payload = decode_header_and_payload(header_segment, payload_segment)
23
+ @signature = Decode.base64url_decode(crypto_segment.to_s) if @verify
24
+ signing_input = [header_segment, payload_segment].join('.')
25
+ [@header, @payload, @signature, signing_input]
26
+ end
27
+
28
+ def raw_segments(jwt, verify)
29
+ segments = jwt.split('.')
30
+ required_num_segments = verify ? [3] : [2, 3]
31
+ fail(JWT::DecodeError, 'Not enough or too many segments') unless required_num_segments.include? segments.length
32
+ segments
33
+ end
34
+ private :raw_segments
35
+
36
+ def decode_header_and_payload(header_segment, payload_segment)
37
+ header = JWT.decode_json(Decode.base64url_decode(header_segment))
38
+ payload = JWT.decode_json(Decode.base64url_decode(payload_segment))
39
+ [header, payload]
40
+ end
41
+ private :decode_header_and_payload
42
+
43
+ def self.base64url_decode(str)
44
+ str += '=' * (4 - str.length.modulo(4))
45
+ Base64.decode64(str.tr('-_', '+/'))
46
+ end
47
+
48
+ def verify
49
+ @options.each do |key, val|
50
+ next unless key.to_s.match(/verify/)
51
+
52
+ Verify.send(key, payload, @options) if val
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,12 @@
1
+ module JWT
2
+ class DecodeError < StandardError; end
3
+ class VerificationError < DecodeError; end
4
+ class ExpiredSignature < DecodeError; end
5
+ class IncorrectAlgorithm < DecodeError; end
6
+ class ImmatureSignature < DecodeError; end
7
+ class InvalidIssuerError < DecodeError; end
8
+ class InvalidIatError < DecodeError; end
9
+ class InvalidAudError < DecodeError; end
10
+ class InvalidSubError < DecodeError; end
11
+ class InvalidJtiError < DecodeError; end
12
+ end
@@ -1,32 +1,16 @@
1
- # encoding: utf-8
1
+ require 'json'
2
+
2
3
  module JWT
3
4
  # JSON fallback implementation or ruby 1.8.x
4
5
  module Json
5
- if RUBY_VERSION >= '1.9' && !defined?(MultiJson)
6
- require 'json'
7
-
8
- def decode_json(encoded)
9
- JSON.parse(encoded)
10
- rescue JSON::ParserError
11
- raise JWT::DecodeError, 'Invalid segment encoding'
12
- end
13
-
14
- def encode_json(raw)
15
- JSON.generate(raw)
16
- end
17
-
18
- else
19
- require 'multi_json'
20
-
21
- def decode_json(encoded)
22
- MultiJson.decode(encoded)
23
- rescue MultiJson::LoadError
24
- raise JWT::DecodeError, 'Invalid segment encoding'
25
- end
6
+ def decode_json(encoded)
7
+ JSON.parse(encoded)
8
+ rescue JSON::ParserError
9
+ raise JWT::DecodeError, 'Invalid segment encoding'
10
+ end
26
11
 
27
- def encode_json(raw)
28
- MultiJson.encode(raw)
29
- end
12
+ def encode_json(raw)
13
+ JSON.generate(raw)
30
14
  end
31
15
  end
32
16
  end