devise-jwt 0.1.1 → 0.2.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 +9 -0
- data/README.md +3 -2
- data/lib/devise/jwt.rb +24 -1
- data/lib/devise/jwt/defaults_generator.rb +65 -40
- data/lib/devise/jwt/mapping_inspector.rb +69 -0
- data/lib/devise/jwt/railtie.rb +5 -5
- data/lib/devise/jwt/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abe51a448ee1c23ead964f1d3fd53ef1a0f1443d
|
4
|
+
data.tar.gz: 7731662d778cc78da4265f7850d071f8632d7d99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 174b7dc71c02263dc0be659bac3c4cc980b37e80cc735c980845c0a7f9a2732eebfd0956b0b473bc3da0e9e7b14c85365a4465ac243fa75367435bdf7fc8f03a
|
7
|
+
data.tar.gz: 6df5de828db92a655a6ecdef225f7bfb3680479c9bcb8ef6769323430f7420371135d7a675992f301b7eb32ee7619ce9f1fc878e9da7454641273cc11e77a098
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
+
## [0.2.0] - 2017-02-28
|
8
|
+
### Added
|
9
|
+
- Dispatch token on sign up
|
10
|
+
- Speed up initialization
|
11
|
+
### Fixed
|
12
|
+
- Do not depend on assumed helpers to build default paths
|
13
|
+
- Use `sign_out_via` devise option to set revocation request methods
|
14
|
+
- Take routes with scopes into account
|
15
|
+
|
7
16
|
## [0.1.1] - 2017-01-26
|
8
17
|
### Fixed
|
9
18
|
- Request method configuration for Rails < 5
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Devise::JWT
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/devise-jwt)
|
3
4
|
[](https://travis-ci.org/waiting-for-dev/devise-jwt)
|
4
5
|
[](https://codeclimate.com/github/waiting-for-dev/devise-jwt)
|
5
6
|
[](https://codeclimate.com/github/waiting-for-dev/devise-jwt/coverage)
|
@@ -11,7 +12,7 @@ You can read about which security concerns this library takes into account and a
|
|
11
12
|
- [Stand Up for JWT Revocation](http://waiting-for-dev.github.io/blog/2017/01/23/stand_up_for_jwt_revocation/)
|
12
13
|
- [JWT Recovation Strategies](http://waiting-for-dev.github.io/blog/2017/01/24/jwt_revocation_strategies/)
|
13
14
|
- [JWT Secure Usage](http://waiting-for-dev.github.io/blog/2017/01/25/jwt_secure_usage/)
|
14
|
-
- [A secure JWT authentication implementation for Rack and Rails](http://waiting-for-dev.github.io/blog/2017/01/26/
|
15
|
+
- [A secure JWT authentication implementation for Rack and Rails](http://waiting-for-dev.github.io/blog/2017/01/26/a_secure_jwt_authentication_implementation_for_rack_and_rails/)
|
15
16
|
|
16
17
|
`devise-jwt` is just a thin layer on top of [`warden-jwt_auth`](https://github.com/waiting-for-dev/warden-jwt_auth) that configures it to be used out of the box with devise and Rails.
|
17
18
|
|
@@ -55,7 +56,7 @@ Currently, HS256 algorithm is the one in use.
|
|
55
56
|
You have to tell which user models you want to be able to authenticate with JWT tokens. For them, the authentication process will be like this:
|
56
57
|
|
57
58
|
- A user authenticates trough devise create session request (for example, using the standard `:database_authenticatable` module).
|
58
|
-
- If the authentication succeeds, a JWT token is dispatched to the client in the `Authorization` response header, with format `Bearer #{token}`
|
59
|
+
- If the authentication succeeds, a JWT token is dispatched to the client in the `Authorization` response header, with format `Bearer #{token}` (tokens are also dispatched on a successful sign up).
|
59
60
|
- The client can use this token to authenticate following requests for the same user, providing it in the `Authorization` request header, also with format `Bearer #{token}`
|
60
61
|
- When the client visits devise destroy session request, the token is revoked.
|
61
62
|
|
data/lib/devise/jwt.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'forwardable'
|
3
4
|
require 'devise'
|
4
5
|
require 'active_support/core_ext/module/attribute_accessors'
|
5
6
|
require 'warden/jwt_auth'
|
6
7
|
require 'devise/jwt/version'
|
8
|
+
require 'devise/jwt/mapping_inspector'
|
7
9
|
require 'devise/jwt/defaults_generator'
|
8
10
|
require 'devise/jwt/railtie'
|
9
11
|
require 'devise/jwt/models'
|
@@ -15,12 +17,33 @@ module Devise
|
|
15
17
|
#
|
16
18
|
# @see Warden::JWTAuth
|
17
19
|
def self.jwt
|
18
|
-
yield(
|
20
|
+
yield(Devise::JWT.config)
|
19
21
|
end
|
20
22
|
|
21
23
|
add_module(:jwt_authenticatable, strategy: :jwt)
|
22
24
|
|
23
25
|
# JWT extension for devise
|
24
26
|
module JWT
|
27
|
+
extend Dry::Configurable
|
28
|
+
|
29
|
+
setting(:secret) do |value|
|
30
|
+
forward_to_warden(:secret, value)
|
31
|
+
end
|
32
|
+
|
33
|
+
setting(:expiration_time) do |value|
|
34
|
+
forward_to_warden(:expiration_time, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
setting(:dispatch_requests) do |value|
|
38
|
+
forward_to_warden(:dispatch_requests, value)
|
39
|
+
end
|
40
|
+
|
41
|
+
setting(:revocation_requests) do |value|
|
42
|
+
forward_to_warden(:revocation_requests, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.forward_to_warden(setting, value)
|
46
|
+
Warden::JWTAuth.config.send("#{setting}=", value)
|
47
|
+
end
|
25
48
|
end
|
26
49
|
end
|
@@ -7,66 +7,91 @@ module Devise
|
|
7
7
|
#
|
8
8
|
# @see Warden::JWTAuth
|
9
9
|
class DefaultsGenerator
|
10
|
-
attr_reader :
|
10
|
+
attr_reader :devise_mappings, :defaults
|
11
|
+
|
12
|
+
def self.call
|
13
|
+
new.call
|
14
|
+
end
|
11
15
|
|
12
16
|
def initialize
|
13
|
-
@routes = Rails.application.routes
|
14
17
|
@devise_mappings = Devise.mappings
|
18
|
+
@defaults = {
|
19
|
+
mappings: {},
|
20
|
+
revocation_strategies: {},
|
21
|
+
dispatch_requests: [],
|
22
|
+
revocation_requests: []
|
23
|
+
}
|
15
24
|
end
|
16
25
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
hash[scope] = mapping.to
|
26
|
+
def call
|
27
|
+
devise_mappings.each_key do |scope|
|
28
|
+
inspector = MappingInspector.new(scope)
|
29
|
+
next unless inspector.jwt?
|
30
|
+
add_defaults(inspector)
|
23
31
|
end
|
32
|
+
defaults
|
24
33
|
end
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
35
|
+
private
|
36
|
+
|
37
|
+
def add_defaults(inspector)
|
38
|
+
add_mapping(inspector)
|
39
|
+
add_revocation_strategy(inspector)
|
40
|
+
add_dispatch_requests(inspector)
|
41
|
+
add_revocation_requests(inspector)
|
31
42
|
end
|
32
43
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
44
|
+
# :reek:FeatureEnvy
|
45
|
+
def add_mapping(inspector)
|
46
|
+
scope = inspector.scope
|
47
|
+
model = inspector.model
|
48
|
+
defaults[:mappings][scope] = model
|
38
49
|
end
|
39
50
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
51
|
+
# :reek:FeatureEnvy
|
52
|
+
def add_revocation_strategy(inspector)
|
53
|
+
scope = inspector.scope
|
54
|
+
model = inspector.model
|
55
|
+
defaults[:revocation_strategies][scope] = model.jwt_revocation_strategy
|
45
56
|
end
|
46
57
|
|
47
|
-
|
58
|
+
def add_dispatch_requests(inspector)
|
59
|
+
add_sign_in_request(inspector)
|
60
|
+
add_registration_request(inspector)
|
61
|
+
end
|
48
62
|
|
49
|
-
def
|
50
|
-
|
63
|
+
def add_sign_in_request(inspector)
|
64
|
+
return unless inspector.session?
|
65
|
+
defaults[:dispatch_requests] << sign_in_request(inspector)
|
51
66
|
end
|
52
67
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
68
|
+
def add_registration_request(inspector)
|
69
|
+
return unless inspector.registration?
|
70
|
+
defaults[:dispatch_requests] << registration_request(inspector)
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_revocation_requests(inspector)
|
74
|
+
return unless inspector.session?
|
75
|
+
defaults[:revocation_requests] << sign_out_request(inspector)
|
76
|
+
end
|
77
|
+
|
78
|
+
def sign_in_request(inspector)
|
79
|
+
request(inspector, :sign_in)
|
80
|
+
end
|
81
|
+
|
82
|
+
def sign_out_request(inspector)
|
83
|
+
request(inspector, :sign_out)
|
84
|
+
end
|
85
|
+
|
86
|
+
def registration_request(inspector)
|
87
|
+
request(inspector, :registration)
|
59
88
|
end
|
60
89
|
|
61
90
|
# :reek:UtilityFunction
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
verb.source.match(/\w+/)[0]
|
67
|
-
else
|
68
|
-
verb
|
69
|
-
end
|
91
|
+
def request(inspector, name)
|
92
|
+
path = inspector.path(name)
|
93
|
+
method = inspector.method(name)
|
94
|
+
[method, /^#{path}$/]
|
70
95
|
end
|
71
96
|
end
|
72
97
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module JWT
|
5
|
+
# Inspect and extract information from a Devise mapping
|
6
|
+
class MappingInspector
|
7
|
+
attr_reader :scope, :mapping
|
8
|
+
|
9
|
+
def initialize(scope)
|
10
|
+
@scope = scope
|
11
|
+
@mapping = Devise.mappings[scope]
|
12
|
+
end
|
13
|
+
|
14
|
+
def jwt?
|
15
|
+
mapping.modules.member?(:jwt_authenticatable)
|
16
|
+
end
|
17
|
+
|
18
|
+
def session?
|
19
|
+
routes?(:session)
|
20
|
+
end
|
21
|
+
|
22
|
+
def registration?
|
23
|
+
routes?(:registration)
|
24
|
+
end
|
25
|
+
|
26
|
+
def model
|
27
|
+
mapping.to
|
28
|
+
end
|
29
|
+
|
30
|
+
def path(name)
|
31
|
+
prefix, scope, request = path_parts(name)
|
32
|
+
[prefix, scope, request].compact.join('/').prepend('/')
|
33
|
+
end
|
34
|
+
|
35
|
+
# :reek:ControlParameter
|
36
|
+
def method(name)
|
37
|
+
case name
|
38
|
+
when :sign_in
|
39
|
+
'POST'
|
40
|
+
when :sign_out
|
41
|
+
sign_out_via.to_s.upcase
|
42
|
+
when :registration
|
43
|
+
'POST'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def path_parts(name)
|
50
|
+
prefix = mapping.instance_variable_get(:@path_prefix)
|
51
|
+
path = mapping.path
|
52
|
+
path_name = mapping.path_names[name]
|
53
|
+
[
|
54
|
+
prefix && prefix.gsub(%r{^/}, ''),
|
55
|
+
path,
|
56
|
+
path_name && !path_name.empty? ? path_name : nil
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
def routes?(name)
|
61
|
+
mapping.routes.member?(name)
|
62
|
+
end
|
63
|
+
|
64
|
+
def sign_out_via
|
65
|
+
mapping.sign_out_via.to_s.upcase
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/devise/jwt/railtie.rb
CHANGED
@@ -13,12 +13,12 @@ module Devise
|
|
13
13
|
Rails.application.reload_routes!
|
14
14
|
|
15
15
|
Warden::JWTAuth.configure do |config|
|
16
|
-
defaults = DefaultsGenerator.
|
16
|
+
defaults = DefaultsGenerator.call
|
17
17
|
|
18
|
-
config.mappings = defaults
|
19
|
-
config.dispatch_requests.push(*defaults
|
20
|
-
config.revocation_requests.push(*defaults
|
21
|
-
config.revocation_strategies = defaults
|
18
|
+
config.mappings = defaults[:mappings]
|
19
|
+
config.dispatch_requests.push(*defaults[:dispatch_requests])
|
20
|
+
config.revocation_requests.push(*defaults[:revocation_requests])
|
21
|
+
config.revocation_strategies = defaults[:revocation_strategies]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/lib/devise/jwt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise-jwt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Busqué
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: devise
|
@@ -192,6 +192,7 @@ files:
|
|
192
192
|
- docker-compose.yml
|
193
193
|
- lib/devise/jwt.rb
|
194
194
|
- lib/devise/jwt/defaults_generator.rb
|
195
|
+
- lib/devise/jwt/mapping_inspector.rb
|
195
196
|
- lib/devise/jwt/models.rb
|
196
197
|
- lib/devise/jwt/models/jwt_authenticatable.rb
|
197
198
|
- lib/devise/jwt/railtie.rb
|
@@ -220,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
221
|
version: '0'
|
221
222
|
requirements: []
|
222
223
|
rubyforge_project:
|
223
|
-
rubygems_version: 2.6.
|
224
|
+
rubygems_version: 2.6.8
|
224
225
|
signing_key:
|
225
226
|
specification_version: 4
|
226
227
|
summary: JWT authentication for devise
|