jwt_sessions 2.4.3 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +27 -6
- data/lib/jwt_sessions/errors.rb +1 -0
- data/lib/jwt_sessions/token.rb +3 -1
- data/lib/jwt_sessions/version.rb +1 -1
- data/test/units/jwt_sessions/test_token.rb +1 -1
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cb5fdf14070b5d76ee868b427684fba6797cada31600e28b3346c601d7a3079e
|
4
|
+
data.tar.gz: fb709c41d45a11ea6e5b2d93f991326c0ddd4a562995dc837099af138b86ee08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 742c465fe4f58ca7327cc1257b98e21f658e891c12e5637bde92c8ca48010a284db43ec8af0ff53454f6642927a1de1cb2b5473619d7c5ecdaba706fba6e4527
|
7
|
+
data.tar.gz: 6247a76e67522e23211a6a6791312d6c50b06598b34743a92f7c32ec841a75928a6eae08d17fc3968fb9cff3ec886efcf7e0a19fe7bea9291dc7b0560fd0a658
|
data/README.md
CHANGED
@@ -15,10 +15,11 @@ XSS/CSRF safe JWT auth designed for SPA
|
|
15
15
|
- [Rails integration](#rails-integration)
|
16
16
|
- [Non-Rails usage](#non-rails-usage)
|
17
17
|
- [Configuration](#configuration)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
- [Token store](#token-store)
|
19
|
+
- [JWT signature](#jwt-signature)
|
20
|
+
- [Request headers and cookies names](#request-headers-and-cookies-names)
|
21
|
+
- [Expiration time](#expiration-time)
|
22
|
+
- [Exceptions](#exceptions)
|
22
23
|
- [CSRF and cookies](#csrf-and-cookies)
|
23
24
|
- [Refresh with access token](#refresh-with-access-token)
|
24
25
|
- [Refresh token hijack protection](#refresh-token-hijack-protection)
|
@@ -441,6 +442,15 @@ JWTSessions.refresh_exp_time = 604800 # 1 week in seconds
|
|
441
442
|
|
442
443
|
It is defined globally, but can be overridden on a session level. See `JWTSessions::Session.new` options for more info.
|
443
444
|
|
445
|
+
##### Exceptions
|
446
|
+
|
447
|
+
`JWTSessions::Errors::Error` - base class, all possible exceptions are inhereted from it. \
|
448
|
+
`JWTSessions::Errors::Malconfigured` - some required gem settings are empty, or methods are not implemented. \
|
449
|
+
`JWTSessions::Errors::InvalidPayload` - token's payload doesn't contain required keys or they are invalid. \
|
450
|
+
`JWTSessions::Errors::Unauthorized` - token can't be decoded or JWT claims are invalid. \
|
451
|
+
`JWTSessions::Errors::ClaimsVerification` - JWT claims are invalid (inherited from `JWTSessions::Errors::Unauthorized`). \
|
452
|
+
`JWTSessions::Errors::Expired` - token is expired (inherited from `JWTSessions::Errors::Unauthorized`).
|
453
|
+
|
444
454
|
#### CSRF and cookies
|
445
455
|
|
446
456
|
When you use cookies as your tokens transport it becomes vulnerable to CSRF. That is why both the login and refresh methods of the `Session` class produce CSRF tokens for you. `Authorization` mixin expects that this token is sent with all requests except GET and HEAD in a header specified among this gem's settings (`X-CSRF-Token` by default). Verification will be done automatically and the `Authorization` exception will be raised in case of a mismatch between the token from the header and the one stored in the session. \
|
@@ -455,7 +465,7 @@ session.masked_csrf(access_token)
|
|
455
465
|
|
456
466
|
Sometimes it is not secure enough to store the refresh tokens in web / JS clients. \
|
457
467
|
This is why you have the option to only use an access token and to not pass the refresh token to the client at all. \
|
458
|
-
Session accepts `refresh_by_access_allowed: true` setting, which links the access token to the corresponding refresh token.
|
468
|
+
Session accepts `refresh_by_access_allowed: true` setting, which links the access token to the corresponding refresh token.
|
459
469
|
|
460
470
|
Example Rails login controller, which passes an access token token via cookies and renders CSRF:
|
461
471
|
|
@@ -490,7 +500,18 @@ tokens = session.refresh_by_access_payload
|
|
490
500
|
|
491
501
|
In case of token forgery and successful refresh performed by an attacker the original user will have to logout. \
|
492
502
|
To protect the endpoint use the before_action `authorize_refresh_by_access_request!`. \
|
493
|
-
Refresh should be performed once the access token is already expired and we need to use the `claimless_payload` method in order to skip JWT expiration validation (and other claims) in order to proceed.
|
503
|
+
Refresh should be performed once the access token is already expired and we need to use the `claimless_payload` method in order to skip JWT expiration validation (and other claims) in order to proceed.
|
504
|
+
|
505
|
+
Optionally `refresh_by_access_payload` accepts a block argument (the same way `refresh` method does).
|
506
|
+
The block will be called if the refresh action is performed before the access token is expired.
|
507
|
+
Thereby it's possible to prohibit users from making refresh calls while their access token is still active.
|
508
|
+
|
509
|
+
```ruby
|
510
|
+
tokens = session.refresh_by_access_payload do
|
511
|
+
# here goes malicious activity alert
|
512
|
+
raise JWTSessions::Errors::Unauthorized, "Refresh action is performed before the expiration of the access token."
|
513
|
+
end
|
514
|
+
```
|
494
515
|
|
495
516
|
Example Rails refresh by access controller with cookies as token transport:
|
496
517
|
|
data/lib/jwt_sessions/errors.rb
CHANGED
data/lib/jwt_sessions/token.rb
CHANGED
@@ -13,7 +13,9 @@ module JWTSessions
|
|
13
13
|
def decode(token, claims = {})
|
14
14
|
decode_options = { algorithm: JWTSessions.algorithm }.merge(JWTSessions.jwt_options.to_h).merge(claims)
|
15
15
|
JWT.decode(token, JWTSessions.public_key, JWTSessions.validate?, decode_options)
|
16
|
-
rescue JWT::
|
16
|
+
rescue JWT::ExpiredSignature => e
|
17
|
+
raise Errors::Expired, e.message
|
18
|
+
rescue JWT::InvalidIssuerError, JWT::InvalidIatError, JWT::InvalidAudError, JWT::InvalidSubError, JWT::InvalidJtiError => e
|
17
19
|
raise Errors::ClaimsVerification, e.message
|
18
20
|
rescue JWT::DecodeError => e
|
19
21
|
raise Errors::Unauthorized, e.message
|
data/lib/jwt_sessions/version.rb
CHANGED
@@ -142,7 +142,7 @@ class TestToken < Minitest::Test
|
|
142
142
|
|
143
143
|
def test_payload_exp_time
|
144
144
|
token = JWTSessions::Token.encode(payload.merge(exp: Time.now.to_i - (3600 * 24)))
|
145
|
-
assert_raises JWTSessions::Errors::
|
145
|
+
assert_raises JWTSessions::Errors::Expired do
|
146
146
|
JWTSessions::Token.decode(token)
|
147
147
|
end
|
148
148
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt_sessions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yulia Oletskaya
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|
@@ -136,18 +136,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
|
-
|
140
|
-
rubygems_version: 2.6.13
|
139
|
+
rubygems_version: 3.0.3
|
141
140
|
signing_key:
|
142
141
|
specification_version: 4
|
143
142
|
summary: JWT Sessions
|
144
143
|
test_files:
|
145
144
|
- test/units/test_jwt_sessions.rb
|
146
145
|
- test/units/test_token_store.rb
|
147
|
-
- test/units/jwt_sessions/store_adapters/test_memory_store_adapter.rb
|
148
|
-
- test/units/jwt_sessions/store_adapters/test_redis_store_adapter.rb
|
149
|
-
- test/units/jwt_sessions/test_access_token.rb
|
150
146
|
- test/units/jwt_sessions/test_csrf_token.rb
|
147
|
+
- test/units/jwt_sessions/test_access_token.rb
|
148
|
+
- test/units/jwt_sessions/store_adapters/test_redis_store_adapter.rb
|
149
|
+
- test/units/jwt_sessions/store_adapters/test_memory_store_adapter.rb
|
150
|
+
- test/units/jwt_sessions/test_token.rb
|
151
151
|
- test/units/jwt_sessions/test_refresh_token.rb
|
152
152
|
- test/units/jwt_sessions/test_session.rb
|
153
|
-
- test/units/jwt_sessions/test_token.rb
|