jwt-auth 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +48 -19
- data/.travis.yml +11 -0
- data/README.md +1 -1
- data/jwt-auth.gemspec +24 -21
- data/lib/jwt/auth/authentication.rb +3 -3
- data/lib/jwt/auth/token.rb +14 -3
- data/lib/jwt/auth/version.rb +1 -1
- data/spec/authentication_spec.rb +95 -0
- data/spec/configuration_spec.rb +1 -1
- data/spec/dummy/.gitignore +41 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +4 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/javascripts/channels/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +13 -0
- data/spec/dummy/app/controllers/authentication_controller.rb +15 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/authentication_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/user.rb +14 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +38 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/bin/yarn +11 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +18 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +54 -0
- data/spec/dummy/config/environments/production.rb +91 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/jwt_auth.rb +11 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +56 -0
- data/spec/dummy/config/routes.rb +6 -0
- data/spec/dummy/config/secrets.yml +32 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/migrate/20170726110751_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20170726110825_add_token_version_to_user.rb +5 -0
- data/spec/dummy/db/migrate/20170726112117_add_activated_to_user.rb +5 -0
- data/spec/dummy/db/schema.rb +23 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/.keep +0 -0
- data/spec/rails_helper.rb +50 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/support/.keep +0 -0
- data/spec/token_spec.rb +76 -4
- metadata +196 -18
- data/spec/support/dummy_user.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cd012fc046f4777af5d9ee5f6265f5ca2d62af9
|
4
|
+
data.tar.gz: 9170ff259b31aa1867b40da3572db62b4b1af852
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cee44e1a66ed06d4ecb6298542b45b13c72a2806c271805c2e8772dcab5b755ad4f9cf9c862c8f507a511744fa52c28e600c458b48ef50b555ca6ae1e946afb1
|
7
|
+
data.tar.gz: b34a80b8d6bb0f0cf068b4505101edbc9030f96bcccf3bd5b5bcb5ffe55b7e7fd77726177dbb2ac68b3fe1981edf2c68ecdd5a04a54d7b2ff2d2ab9dbb4c8eda
|
data/.gitignore
CHANGED
@@ -1,25 +1,54 @@
|
|
1
1
|
*.gem
|
2
2
|
*.rbc
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
.byebug_history
|
13
|
+
|
14
|
+
# Used by dotenv library to load environment variables.
|
15
|
+
# .env
|
16
|
+
|
17
|
+
## Specific to RubyMotion:
|
18
|
+
.dat*
|
19
|
+
.repl_history
|
20
|
+
build/
|
21
|
+
*.bridgesupport
|
22
|
+
build-iPhoneOS/
|
23
|
+
build-iPhoneSimulator/
|
24
|
+
|
25
|
+
## Specific to RubyMotion (use of CocoaPods):
|
26
|
+
#
|
27
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
28
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
29
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
30
|
+
#
|
31
|
+
# vendor/Pods/
|
32
|
+
|
33
|
+
## Documentation cache and generated files:
|
34
|
+
/.yardoc/
|
35
|
+
/_yardoc/
|
36
|
+
/doc/
|
37
|
+
/rdoc/
|
38
|
+
|
39
|
+
## Environment normalization:
|
40
|
+
/.bundle/
|
41
|
+
/vendor/bundle
|
42
|
+
/lib/bundler/man/
|
43
|
+
|
44
|
+
# for a library or gem, you might want to ignore these files since the code is
|
45
|
+
# intended to run in multiple environments; otherwise, check them in:
|
6
46
|
Gemfile.lock
|
7
|
-
InstalledFiles
|
8
|
-
_yardoc
|
9
|
-
coverage
|
10
|
-
doc/
|
11
|
-
lib/bundler/man
|
12
|
-
pkg
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
18
|
-
*.bundle
|
19
|
-
*.so
|
20
|
-
*.o
|
21
|
-
*.a
|
22
|
-
mkmf.log
|
23
47
|
.ruby-version
|
24
48
|
.ruby-gemset
|
49
|
+
|
50
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
51
|
+
.rvmrc
|
52
|
+
|
53
|
+
# IDE files
|
25
54
|
.idea
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# JWT::Auth
|
1
|
+
# JWT::Auth [![Travis](https://travis-ci.org/floriandejonckheere/jwt-auth.svg?branch=master)](https://travis-ci.org/floriandejonckheere/jwt-auth) [![Coverage Status](https://coveralls.io/repos/github/floriandejonckheere/jwt-auth/badge.svg)](https://coveralls.io/github/floriandejonckheere/jwt-auth)
|
2
2
|
|
3
3
|
JWT-based authentication middleware for Rails API without Devise
|
4
4
|
|
data/jwt-auth.gemspec
CHANGED
@@ -6,28 +6,31 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
|
7
7
|
require 'jwt/auth/version'
|
8
8
|
|
9
|
-
Gem::Specification.new do |
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
Gem::Specification.new do |gem|
|
10
|
+
gem.name = 'jwt-auth'
|
11
|
+
gem.version = JWT::Auth::VERSION
|
12
|
+
gem.authors = ['Florian Dejonckheere']
|
13
|
+
gem.email = ['florian@floriandejonckheere.be']
|
14
|
+
gem.summary = 'JWT-based authentication for Rails API'
|
15
|
+
gem.description = 'Authentication middleware for Rails API that uses JWTs'
|
16
|
+
gem.homepage = 'https://github.com/floriandejonckheere/jwt-auth'
|
17
|
+
gem.license = 'MIT'
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
gem.files = `git ls-files -z`.split("\x0")
|
20
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
22
|
+
gem.require_paths = ['lib']
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
gem.add_runtime_dependency 'jwt', '~> 1.5'
|
25
|
+
gem.add_runtime_dependency 'rails', '~> 5.1'
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
gem.add_development_dependency 'bundler', '~> 1.15'
|
28
|
+
gem.add_development_dependency 'rubocop', '~> 0.49'
|
29
|
+
gem.add_development_dependency 'rake', '~> 12.0'
|
30
|
+
gem.add_development_dependency 'rspec', '~> 3.6'
|
31
|
+
gem.add_development_dependency 'rspec-rails', '~> 3.6'
|
32
|
+
gem.add_development_dependency 'rdoc', '~> 5.1'
|
33
|
+
gem.add_development_dependency 'coveralls', '~> 0.8'
|
34
|
+
gem.add_development_dependency 'byebug'
|
35
|
+
gem.add_development_dependency 'sqlite3'
|
33
36
|
end
|
@@ -12,21 +12,21 @@ module JWT
|
|
12
12
|
# Current user helper
|
13
13
|
#
|
14
14
|
def current_user
|
15
|
-
jwt
|
15
|
+
jwt && jwt.subject
|
16
16
|
end
|
17
17
|
|
18
18
|
##
|
19
19
|
# Authenticate a request
|
20
20
|
#
|
21
21
|
def authenticate_user
|
22
|
-
raise JWT::Auth::UnauthorizedError unless jwt
|
22
|
+
raise JWT::Auth::UnauthorizedError unless jwt && jwt.valid?
|
23
23
|
end
|
24
24
|
|
25
25
|
##
|
26
26
|
# Add JWT header to response
|
27
27
|
#
|
28
28
|
def renew_token
|
29
|
-
return unless jwt
|
29
|
+
return unless jwt && jwt.valid?
|
30
30
|
jwt.renew!
|
31
31
|
response.headers['Authorization'] = "Bearer #{jwt.to_jwt}"
|
32
32
|
end
|
data/lib/jwt/auth/token.rb
CHANGED
@@ -13,11 +13,16 @@ module JWT
|
|
13
13
|
attr_accessor :expiration, :subject, :token_version
|
14
14
|
|
15
15
|
def valid?
|
16
|
+
# Reload subject to prevent caching the old token_version
|
17
|
+
subject && subject.reload
|
18
|
+
|
16
19
|
return false if subject.nil? || expiration.nil? || token_version.nil?
|
17
20
|
return false if Time.at(expiration).past?
|
18
21
|
return false if token_version != subject.token_version
|
19
22
|
|
20
23
|
true
|
24
|
+
rescue ActiveRecord::RecordNotFound
|
25
|
+
false
|
21
26
|
end
|
22
27
|
|
23
28
|
def renew!
|
@@ -42,14 +47,20 @@ module JWT
|
|
42
47
|
end
|
43
48
|
|
44
49
|
def self.from_token(token)
|
45
|
-
|
50
|
+
begin
|
51
|
+
payload = JWT.decode(token, JWT::Auth.secret).first
|
52
|
+
rescue JWT::ExpiredSignature
|
53
|
+
payload = {}
|
54
|
+
end
|
46
55
|
|
47
56
|
token = JWT::Auth::Token.new
|
48
57
|
token.expiration = payload['exp']
|
49
58
|
token.token_version = payload['ver']
|
50
59
|
|
51
|
-
|
52
|
-
|
60
|
+
if payload['sub']
|
61
|
+
find_method = JWT::Auth.model.respond_to?(:find_by_token) ? :find_by_token : :find_by
|
62
|
+
token.subject = JWT::Auth.model.send find_method, :id => payload['sub'], :token_version => payload['ver']
|
63
|
+
end
|
53
64
|
|
54
65
|
token
|
55
66
|
end
|
data/lib/jwt/auth/version.rb
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_listeral: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe AuthenticationController, :type => :request do
|
6
|
+
let(:user) { User.create :activated => true }
|
7
|
+
|
8
|
+
let(:headers) do
|
9
|
+
{
|
10
|
+
'Authorization' => "Bearer #{JWT::Auth::Token.from_user(user).to_jwt}"
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'GET /public' do
|
15
|
+
context 'activated user' do
|
16
|
+
it 'is accessible without token' do
|
17
|
+
get '/public'
|
18
|
+
|
19
|
+
expect(response.status).to eq 204
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'is accessible with token' do
|
23
|
+
get '/public', :headers => headers
|
24
|
+
|
25
|
+
expect(response.status).to eq 204
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'renews the token' do
|
29
|
+
get '/public', :headers => headers
|
30
|
+
|
31
|
+
jwt = response.headers['Authorization'].scan(/Bearer (.*)$/).flatten.last
|
32
|
+
token = JWT::Auth::Token.from_token jwt
|
33
|
+
|
34
|
+
expect(token).to be_valid
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'disabled user' do
|
39
|
+
let(:user) { User.new }
|
40
|
+
|
41
|
+
it 'is accessible without token' do
|
42
|
+
get '/public'
|
43
|
+
|
44
|
+
expect(response.status).to eq 204
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'is accessible with token' do
|
48
|
+
get '/public', :headers => headers
|
49
|
+
|
50
|
+
expect(response.status).to eq 204
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'GET /private' do
|
56
|
+
context 'activated user' do
|
57
|
+
it 'is not accessible without token' do
|
58
|
+
get '/private'
|
59
|
+
|
60
|
+
expect(response.status).to eq 401
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'is accessible with token' do
|
64
|
+
get '/private', :headers => headers
|
65
|
+
|
66
|
+
expect(response.status).to eq 204
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'renews the token' do
|
70
|
+
get '/private', :headers => headers
|
71
|
+
|
72
|
+
jwt = response.headers['Authorization'].scan(/Bearer (.*)$/).flatten.last
|
73
|
+
token = JWT::Auth::Token.from_token jwt
|
74
|
+
|
75
|
+
expect(token).to be_valid
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'disabled user' do
|
80
|
+
let(:user) { User.new }
|
81
|
+
|
82
|
+
it 'is not accessible without token' do
|
83
|
+
get '/private'
|
84
|
+
|
85
|
+
expect(response.status).to eq 401
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'is not accessible with token' do
|
89
|
+
get '/private', :headers => headers
|
90
|
+
|
91
|
+
expect(response.status).to eq 401
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
# Ignore bundler config.
|
8
|
+
/.bundle
|
9
|
+
/.gem
|
10
|
+
|
11
|
+
# Ignore the default SQLite database.
|
12
|
+
/db/*.sqlite3
|
13
|
+
/db/*.sqlite3-journal
|
14
|
+
|
15
|
+
# Ignore all logfiles and tempfiles.
|
16
|
+
/log/*
|
17
|
+
/tmp/*
|
18
|
+
!/log/.keep
|
19
|
+
!/tmp/.keep
|
20
|
+
|
21
|
+
# Ignore Byebug command history file.
|
22
|
+
.byebug_history
|
23
|
+
|
24
|
+
# IDE files
|
25
|
+
.idea
|
26
|
+
|
27
|
+
# Webpack files
|
28
|
+
node_modules
|
29
|
+
/client/public
|
30
|
+
|
31
|
+
# Private files
|
32
|
+
*.env
|
33
|
+
config/*.pem
|
34
|
+
config/*.pub
|
35
|
+
|
36
|
+
# Coverage report
|
37
|
+
coverage/
|
38
|
+
|
39
|
+
/.gem
|
40
|
+
/.vscode
|
41
|
+
.DS_Store
|
data/spec/dummy/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// Action Cable provides the framework to deal with WebSockets in Rails.
|
2
|
+
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
3
|
+
//
|
4
|
+
//= require action_cable
|
5
|
+
//= require_self
|
6
|
+
//= require_tree ./channels
|
7
|
+
|
8
|
+
(function() {
|
9
|
+
this.App || (this.App = {});
|
10
|
+
|
11
|
+
App.cable = ActionCable.createConsumer();
|
12
|
+
|
13
|
+
}).call(this);
|
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|