json_web_token 0.2.2 → 0.3.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +6 -6
- data/lib/json_web_token.rb +3 -2
- data/lib/json_web_token/jws.rb +8 -7
- data/lib/json_web_token/jwt.rb +16 -9
- data/lib/json_web_token/version.rb +1 -1
- data/spec/json_web_token/jws_spec.rb +7 -7
- data/spec/json_web_token/jwt_spec.rb +4 -4
- data/spec/json_web_token_spec.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c926ffcdb482f32a80eb5e1d15100d5e03be4101
|
4
|
+
data.tar.gz: f64c2145334ff5c4df4d65816b2295de71a87ead
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6b6b657427e96afc712ff7fcb2af970a1a77ceba8d3579491076ea3fe2b139c51341518778d89475d1e8a1db54fec1046d89f5577ed86fcbcd10149d451ddd0
|
7
|
+
data.tar.gz: 4f658d73cfc3efd1a4f80aa96e93a7884d6a05a1e83fd6d7ad346a6407eb697c04882b8dd5900c71c8c2094785cdac0a8bbfc23f50b33d8d2946e15ca3a0914f
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -64,9 +64,9 @@ jwt = JsonWebToken.sign({foo: 'bar'}, alg: 'none')
|
|
64
64
|
|
65
65
|
### JsonWebToken.verify(jwt, options)
|
66
66
|
|
67
|
-
Returns
|
68
|
-
*
|
69
|
-
*
|
67
|
+
Returns a hash:
|
68
|
+
* \{ok: < JWT claims set >\}, if the Message Authentication Code (MAC), or signature, is verified
|
69
|
+
* \{error: 'invalid'\}, otherwise
|
70
70
|
|
71
71
|
`jwt` (required) is a JSON web token string
|
72
72
|
|
@@ -83,7 +83,7 @@ require 'json_web_token'
|
|
83
83
|
secure_jwt_example = 'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt.cGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
|
84
84
|
|
85
85
|
# verify with default algorithm, HMAC SHA256
|
86
|
-
claims = JsonWebToken.verify(secure_jwt_example, key: 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C')
|
86
|
+
\{ok: claims\} = JsonWebToken.verify(secure_jwt_example, key: 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C')
|
87
87
|
|
88
88
|
# verify with RSA SHA256 algorithm
|
89
89
|
opts = {
|
@@ -91,12 +91,12 @@ opts = {
|
|
91
91
|
key: < RSA public key >
|
92
92
|
}
|
93
93
|
|
94
|
-
claims = JsonWebToken.verify(jwt, opts)
|
94
|
+
\{ok: claims\} = JsonWebToken.verify(jwt, opts)
|
95
95
|
|
96
96
|
# unsecured token (algorithm is 'none')
|
97
97
|
unsecured_jwt_example = 'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt.'
|
98
98
|
|
99
|
-
claims = JsonWebToken.verify(unsecured_jwt_example, alg: 'none')
|
99
|
+
\{ok: claims\} = JsonWebToken.verify(unsecured_jwt_example, alg: 'none')
|
100
100
|
|
101
101
|
```
|
102
102
|
### Supported encryption algorithms
|
data/lib/json_web_token.rb
CHANGED
@@ -20,12 +20,13 @@ module JsonWebToken
|
|
20
20
|
|
21
21
|
# @param jwt [String] a JSON Web Token
|
22
22
|
# @param options [Hash] specify the desired verifying algorithm and verifying key
|
23
|
-
# @return [Hash]
|
23
|
+
# @return [Hash] +{ok: < the jwt claims set hash >}+ if the jwt verifies,
|
24
|
+
# or +{error: 'Invalid'}+ otherwise
|
24
25
|
# @example
|
25
26
|
# jwt = 'eyJhbGciOiJIUzI1NiJ9.cGF5bG9hZA.uVTaOdyzp_f4mT_hfzU8LnCzdmlVC4t2itHDEYUZym4'
|
26
27
|
# options = {alg: 'HS256', key: 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C'}
|
27
28
|
# JsonWebToken.verify(jwt, options)
|
28
|
-
# # => {iss: 'joe', exp: 1300819380, :'http://example.com/is_root' => true}
|
29
|
+
# # => {ok: {iss: 'joe', exp: 1300819380, :'http://example.com/is_root' => true}}
|
29
30
|
def verify(jwt, options)
|
30
31
|
Jwt.verify(jwt, options)
|
31
32
|
end
|
data/lib/json_web_token/jws.rb
CHANGED
@@ -46,17 +46,18 @@ module JsonWebToken
|
|
46
46
|
# @param algorithm [String] 'alg' header parameter value for JWS
|
47
47
|
# @param key [String | OpenSSL::PKey::RSA | OpenSSL::PKey::EC] key used to verify
|
48
48
|
# a digital signature, or mac
|
49
|
-
# @return [
|
49
|
+
# @return [Hash] +{ok: <the jws string>}+ if the mac verifies,
|
50
|
+
# or +{error: 'invalid'}+ otherwise
|
50
51
|
# @example
|
51
52
|
# jws = 'eyJhbGciOiJIUzI1NiJ9.cGF5bG9hZA.uVTaOdyzp_f4mT_hfzU8LnCzdmlVC4t2itHDEYUZym4'
|
52
53
|
# key = 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C'
|
53
54
|
# Jws.verify(jws, 'HS256', key)
|
54
|
-
# # => 'eyJhbGciOiJIUzI1NiJ9.cGF5bG9hZA.uVTaOdyzp_f4mT_hfzU8LnCzdmlVC4t2itHDEYUZym4'
|
55
|
+
# # => {ok: 'eyJhbGciOiJIUzI1NiJ9.cGF5bG9hZA.uVTaOdyzp_f4mT_hfzU8LnCzdmlVC4t2itHDEYUZym4'}
|
55
56
|
# @see http://tools.ietf.org/html/rfc7515#page-16
|
56
57
|
def verify(jws, algorithm, key = nil)
|
57
|
-
|
58
|
-
return jws if algorithm == 'none'
|
59
|
-
signature_verify?(jws, algorithm, key) ? jws :
|
58
|
+
validate_alg_match(jws, algorithm)
|
59
|
+
return {ok: jws} if algorithm == 'none'
|
60
|
+
signature_verify?(jws, algorithm, key) ? {ok: jws} : {error: 'invalid'}
|
60
61
|
end
|
61
62
|
|
62
63
|
def alg_parameter(header)
|
@@ -73,7 +74,7 @@ module JsonWebToken
|
|
73
74
|
end
|
74
75
|
|
75
76
|
# http://tools.ietf.org/html/rfc7515#section-4.1.1
|
76
|
-
def
|
77
|
+
def validate_alg_match(jws, algorithm)
|
77
78
|
header = decoded_header_json_to_hash(jws)
|
78
79
|
unless alg_parameter(header) == algorithm
|
79
80
|
fail("Algorithm not matching 'alg' header parameter")
|
@@ -95,7 +96,7 @@ module JsonWebToken
|
|
95
96
|
private_class_method :alg_parameter,
|
96
97
|
:encode_input,
|
97
98
|
:signature,
|
98
|
-
:
|
99
|
+
:validate_alg_match,
|
99
100
|
:decoded_header_json_to_hash,
|
100
101
|
:signature_verify?
|
101
102
|
end
|
data/lib/json_web_token/jwt.rb
CHANGED
@@ -34,17 +34,17 @@ module JsonWebToken
|
|
34
34
|
|
35
35
|
# @param jwt [String] a JSON Web Token
|
36
36
|
# @param options [Hash] specify the desired verifying algorithm and verifying key
|
37
|
-
# @return [Hash]
|
37
|
+
# @return [Hash] +{ok: <the jwt claims set hash>}+ if the jwt verifies,
|
38
|
+
# or +{error: 'Invalid'}+ otherwise
|
38
39
|
# @example
|
39
40
|
# jwt = 'eyJhbGciOiJIUzI1NiJ9.cGF5bG9hZA.uVTaOdyzp_f4mT_hfzU8LnCzdmlVC4t2itHDEYUZym4'
|
40
41
|
# options = {alg: 'HS256', key: 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9C'}
|
41
42
|
# Jwt.verify(jwt, options)
|
42
|
-
# # => {iss: 'joe', exp: 1300819380, :'http://example.com/is_root' => true}
|
43
|
+
# # => {ok: {iss: 'joe', exp: 1300819380, :'http://example.com/is_root' => true}}
|
43
44
|
# @see see http://tools.ietf.org/html/rfc7519#section-7.2
|
44
45
|
def verify(jwt, options)
|
45
46
|
alg = options[:alg] || ALG_DEFAULT
|
46
|
-
|
47
|
-
jws ? Util.symbolize_keys(decoded_message_json_to_hash jws) : {error: 'invalid'}
|
47
|
+
payload(Jws.verify(jwt, alg, options[:key]))
|
48
48
|
end
|
49
49
|
|
50
50
|
def validated_message(claims)
|
@@ -62,15 +62,22 @@ module JsonWebToken
|
|
62
62
|
alg && !alg.empty? ? hsh : {}
|
63
63
|
end
|
64
64
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
def payload(hsh)
|
66
|
+
return {error: 'invalid'} if hsh[:error]
|
67
|
+
ary = hsh[:ok].split('.')
|
68
|
+
return {error: 'invalid JWS'} unless ary.length > 1
|
69
|
+
encoded_claims = ary[1]
|
70
|
+
{ok: payload_to_hash(encoded_claims)}
|
71
|
+
end
|
72
|
+
|
73
|
+
def payload_to_hash(encoded_claims)
|
74
|
+
Util.symbolize_keys(JSON.parse(Format::Base64Url.decode encoded_claims))
|
69
75
|
end
|
70
76
|
|
71
77
|
private_class_method :validated_message,
|
72
78
|
:config_header,
|
73
79
|
:alg_parameter_required,
|
74
|
-
:
|
80
|
+
:payload,
|
81
|
+
:payload_to_hash
|
75
82
|
end
|
76
83
|
end
|
@@ -9,7 +9,7 @@ module JsonWebToken
|
|
9
9
|
shared_examples_for 'does #verify' do
|
10
10
|
it 'w a jws' do
|
11
11
|
jws = Jws.sign(header, payload, signing_key)
|
12
|
-
expect(Jws.verify jws, algorithm, verifying_key).to
|
12
|
+
expect(Jws.verify jws, algorithm, verifying_key).to include({ok: jws})
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -23,17 +23,17 @@ module JsonWebToken
|
|
23
23
|
it_behaves_like 'does #verify'
|
24
24
|
|
25
25
|
describe 'w/o passing key to #verify' do
|
26
|
-
it 'returns
|
26
|
+
it 'returns error' do
|
27
27
|
jws = Jws.sign(header, payload, signing_key)
|
28
|
-
expect(Jws.verify jws, algorithm, nil).to
|
28
|
+
expect(Jws.verify jws, algorithm, nil).to include({error: 'invalid'})
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
describe 'w passing a changed key to #verify' do
|
33
33
|
let(:changed_key) { 'gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr9Z' }
|
34
|
-
it 'returns
|
34
|
+
it 'returns error' do
|
35
35
|
jws = Jws.sign(header, payload, signing_key)
|
36
|
-
expect(Jws.verify jws, algorithm, changed_key).to
|
36
|
+
expect(Jws.verify jws, algorithm, changed_key).to include({error: 'invalid'})
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -59,7 +59,7 @@ module JsonWebToken
|
|
59
59
|
public_key = EcdsaKey.public_key_new('256', public_key_str)
|
60
60
|
|
61
61
|
jws = Jws.sign(header, payload, private_key)
|
62
|
-
expect(Jws.verify jws, algorithm, public_key).to
|
62
|
+
expect(Jws.verify jws, algorithm, public_key).to include({ok: jws})
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -91,7 +91,7 @@ module JsonWebToken
|
|
91
91
|
let(:algorithm) { 'none' }
|
92
92
|
it 'w a jws' do
|
93
93
|
jws = Jws.unsecured_message(header, payload)
|
94
|
-
expect(Jws.verify jws, algorithm).to
|
94
|
+
expect(Jws.verify jws, algorithm).to include({ok: jws})
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -8,7 +8,7 @@ module JsonWebToken
|
|
8
8
|
shared_examples_for 'does #verify' do
|
9
9
|
it 'w a claims set' do
|
10
10
|
jwt = Jwt.sign(claims, sign_options)
|
11
|
-
expect(Jwt.verify
|
11
|
+
expect(Jwt.verify(jwt, verify_options)[:ok]).to include(claims)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -61,7 +61,7 @@ module JsonWebToken
|
|
61
61
|
|
62
62
|
describe 'w/o key w default header alg' do
|
63
63
|
it 'raises' do
|
64
|
-
expect {
|
64
|
+
expect { Jwt.sign(claims, {}) }
|
65
65
|
.to raise_error(RuntimeError, 'Invalid shared key')
|
66
66
|
end
|
67
67
|
end
|
@@ -88,7 +88,7 @@ module JsonWebToken
|
|
88
88
|
jwt = Jwt.sign(claims, sign_options)
|
89
89
|
|
90
90
|
verify_options = {alg: algorithm, key: public_key}
|
91
|
-
expect(Jwt.verify
|
91
|
+
expect(Jwt.verify(jwt, verify_options)[:ok]).to eql claims
|
92
92
|
|
93
93
|
expect(plausible_message_signature? jwt, 64).to be true
|
94
94
|
end
|
@@ -102,7 +102,7 @@ module JsonWebToken
|
|
102
102
|
let(:verify_options) { {alg: 'none'} }
|
103
103
|
it 'verifies a plausible unsecured jws' do
|
104
104
|
jwt = Jwt.sign(claims, sign_options)
|
105
|
-
expect(Jwt.verify
|
105
|
+
expect(Jwt.verify(jwt, verify_options)[:ok]).to include(claims)
|
106
106
|
expect(plausible_unsecured_message? jwt).to be true
|
107
107
|
end
|
108
108
|
end
|
data/spec/json_web_token_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe JsonWebToken do
|
|
6
6
|
shared_examples_for 'w #verify' do
|
7
7
|
it 'w a claims set' do
|
8
8
|
jwt = JsonWebToken.sign(claims, sign_options)
|
9
|
-
expect(JsonWebToken.verify
|
9
|
+
expect(JsonWebToken.verify(jwt, verify_options)[:ok]).to include(claims)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_web_token
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gary Fleshman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|