rails_jwt 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +111 -0
- data/Rakefile +32 -0
- data/app/controllers/rails_jwt/application_controller.rb +5 -0
- data/app/controllers/rails_jwt/authentication.rb +34 -0
- data/app/controllers/rails_jwt/login_controller.rb +28 -0
- data/app/jobs/rails_jwt/application_job.rb +4 -0
- data/app/mailers/rails_jwt/application_mailer.rb +6 -0
- data/app/models/rails_jwt/application_record.rb +5 -0
- data/config/routes.rb +3 -0
- data/lib/generators/rails_jwt/install/install_generator.rb +7 -0
- data/lib/generators/rails_jwt/install/templates/rails_jwt.rb +28 -0
- data/lib/rails_jwt.rb +17 -0
- data/lib/rails_jwt/engine.rb +6 -0
- data/lib/rails_jwt/version.rb +3 -0
- data/lib/tasks/rails_jwt_tasks.rake +4 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 51746f2546b2ae37fb83c84f163ab8f723a3e0b8fec3c013d53efb331d30ba4f
|
4
|
+
data.tar.gz: d612fe860c580023e383779a749e1e12ddd826b2e6cdd8d012d454c58fe55eb3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2965fb423117528d9105140ff6b97abe841835bdd2a86eb88a9d7b17948abbb27ad24a16ab775544f57e0168da247a342724d7c6e4d0175e57731596a72c04b2
|
7
|
+
data.tar.gz: 8f8c347909be432951ad1be9181b736ca23ed02350e40bfd7aa7d442f3eee4068597b107f054d0a223ac42636471af58d683ce13964e74328175db6274e971fa
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2021 Muhammad Aamir
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# RailsJwt
|
2
|
+
Super easy way to add JWT support for Rails API projects.
|
3
|
+
|
4
|
+
## Description
|
5
|
+
This gem makes it super easy to add JWT support in your Rails project. Just a few of quick steps and you are good to go!
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### Requirements
|
10
|
+
Your user model must have an `authenticate` method (that takes a password as its paramter) implemented. A common and quick way is to use [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)
|
11
|
+
|
12
|
+
Alternatively, you can implement your own `authenticate` method, for example, if you want to authenticate with an LDAP server.
|
13
|
+
|
14
|
+
### Installation
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'rails_jwt'
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
```bash
|
23
|
+
$ bundle
|
24
|
+
```
|
25
|
+
|
26
|
+
Execute following to add configuration file in `config/initializers` folder:
|
27
|
+
```bash
|
28
|
+
$ rails g rails_jwt:install
|
29
|
+
```
|
30
|
+
|
31
|
+
Add following line in your routes.rb
|
32
|
+
```ruby
|
33
|
+
mount RailsJwt::Engine => "/auth"
|
34
|
+
```
|
35
|
+
|
36
|
+
Add the following in the controller you would to secure:
|
37
|
+
```ruby
|
38
|
+
include RailsJwt::Authentication
|
39
|
+
before_action :authenticate_user
|
40
|
+
```
|
41
|
+
|
42
|
+
Or you can create a secure controller that you can inherit in the all of the controllers you would like to secure:
|
43
|
+
```ruby
|
44
|
+
class SecureController < ApplicationController
|
45
|
+
include RailsJwt::Authentication
|
46
|
+
before_action :authenticate_user
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
### Authentication
|
51
|
+
|
52
|
+
Send a POST request:
|
53
|
+
```
|
54
|
+
POST /auth/login HTTP/1.1
|
55
|
+
Host: localhost:3000
|
56
|
+
Content-Type: application/json
|
57
|
+
|
58
|
+
{ "user_id": "test@abc.com", "password": "test"}
|
59
|
+
```
|
60
|
+
|
61
|
+
If authentication is successful, you will get a response like this:
|
62
|
+
```
|
63
|
+
{
|
64
|
+
"jwt": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOnsiaWQiOjF9LCJleHAiOjE2MTY4Mjg3NTZ9.gUmZaBjUM-FOM-_9T47ul4mM7c_YG8lF9l11MlGUmBM"
|
65
|
+
}
|
66
|
+
```
|
67
|
+
|
68
|
+
Pass the returned token to the header of your subsequent API call:
|
69
|
+
```
|
70
|
+
GET /users HTTP/1.1
|
71
|
+
Host: localhost:3000
|
72
|
+
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOnsiaWQiOjF9LCJ1c2VyX2lkIjoxLCJlbWFpbCI6Im1haWxAYWFtaXIucGsiLCJhY3RpdmUiOnRydWUsImV4cCI6MTYxNjc4MjU5M30.-lybW5musgaWS-g1mvTtgmeSM_oi1U7Xa_elh68Ph-c
|
73
|
+
```
|
74
|
+
|
75
|
+
## Configuration
|
76
|
+
A number of configuration options are available in `initiliazers/rails_jwt.rb` file. By default user's email will be used as a login id, however that can be modified by changing relevant entry in `rails_jwt.rb` config file (`config.user_id_attr = :login_id`).
|
77
|
+
|
78
|
+
### Custom payload
|
79
|
+
By default the payload looks like following:
|
80
|
+
```
|
81
|
+
{
|
82
|
+
"sub": {
|
83
|
+
"id": 1
|
84
|
+
},
|
85
|
+
"exp": 1616823684
|
86
|
+
}
|
87
|
+
```
|
88
|
+
|
89
|
+
In above payload `sub.id` is the unique id (primary key) of your user object that will be used to lookup the calling user. If you want to add more fields in the payload, you will need to add `jwt_payload` method in your user model:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
def jwt_payload
|
93
|
+
{email: self.email, active: self.active}
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
Addition of above method will create a payload similar to the following:
|
98
|
+
```
|
99
|
+
{
|
100
|
+
"sub": {
|
101
|
+
"id": 1
|
102
|
+
},
|
103
|
+
"email": "test@abc.com",
|
104
|
+
"active": true,
|
105
|
+
"exp": 1616823952
|
106
|
+
}
|
107
|
+
```
|
108
|
+
|
109
|
+
|
110
|
+
## License
|
111
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'RailsJwt'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
load 'rails/tasks/statistics.rake'
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
t.verbose = false
|
30
|
+
end
|
31
|
+
|
32
|
+
task default: :test
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'jwt'
|
2
|
+
|
3
|
+
module RailsJwt::Authentication
|
4
|
+
def authenticate_user
|
5
|
+
begin
|
6
|
+
payload = jwt_payload
|
7
|
+
|
8
|
+
expiry_time = Time.at(payload["exp"])
|
9
|
+
if Time.now > expiry_time
|
10
|
+
render status: :unauthorized
|
11
|
+
end
|
12
|
+
user = User.find(payload["sub"]["id"])
|
13
|
+
if !user.active
|
14
|
+
render status: :unauthorized
|
15
|
+
end
|
16
|
+
|
17
|
+
rescue ActiveRecord::RecordNotFound
|
18
|
+
render status: :unauthorized
|
19
|
+
rescue JWT::DecodeError
|
20
|
+
render status: :unauthorized
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_user
|
25
|
+
payload = jwt_payload
|
26
|
+
User.find(payload["sub"]["id"])
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def jwt_payload
|
31
|
+
token = request.headers['Authorization']&.split&.fetch(-1)
|
32
|
+
JWT.decode(token, Rails.application.secret_key_base)[0]
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_dependency "rails_jwt/application_controller"
|
2
|
+
require 'jwt'
|
3
|
+
|
4
|
+
module RailsJwt
|
5
|
+
class LoginController < ApplicationController
|
6
|
+
def login
|
7
|
+
user = RailsJwt.user_class.send("find_by_#{RailsJwt.user_id_attr}", params[:user_id])
|
8
|
+
|
9
|
+
if user&.respond_to?(:active) && !user.active
|
10
|
+
render status: :unauthorized
|
11
|
+
elsif user&.authenticate(params[:password])
|
12
|
+
token = JWT.encode(create_jwt_payload(user), RailsJwt.token_signature_key.call, 'HS256')
|
13
|
+
render json: {jwt: token}
|
14
|
+
else
|
15
|
+
render status: :unauthorized
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def create_jwt_payload(user)
|
21
|
+
payload = {sub: {id: user.id}}
|
22
|
+
if user.respond_to?(:jwt_payload)
|
23
|
+
payload.merge!(user.jwt_payload)
|
24
|
+
end
|
25
|
+
return (payload.merge!({exp: (Time.now + RailsJwt.token_lifetime).to_i}))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
RailsJwt.setup do |config|
|
2
|
+
|
3
|
+
## Expiration of token
|
4
|
+
## -------------------
|
5
|
+
## How long it will take before a token is expired. Default is nil, which means token is never expired
|
6
|
+
#
|
7
|
+
# config.token_lifetime = nil # Never expires
|
8
|
+
# config.token_lifetime = 1.week # Default
|
9
|
+
|
10
|
+
|
11
|
+
## User class and user id field
|
12
|
+
## -----------------------------
|
13
|
+
## Application User class. This is the model that represents the user being authenticated.
|
14
|
+
##
|
15
|
+
# config.user_class = "User" # Default
|
16
|
+
##
|
17
|
+
## User ID attribute. This is the attribute of user class that will be used as a unique user id
|
18
|
+
##
|
19
|
+
# config.user_id_attr = :email # Default
|
20
|
+
|
21
|
+
|
22
|
+
## Token signature key
|
23
|
+
## -------------------
|
24
|
+
## The secrete key that will be used to sign the token
|
25
|
+
##
|
26
|
+
# config.token_signature_key = -> {Rails.application.secret_key_base} # Default
|
27
|
+
|
28
|
+
end
|
data/lib/rails_jwt.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rails_jwt/engine"
|
2
|
+
|
3
|
+
module RailsJwt
|
4
|
+
mattr_writer :user_class, default: 'User'
|
5
|
+
mattr_accessor :user_id_attr, default: 'email'
|
6
|
+
mattr_accessor :token_lifetime, default: 1.week
|
7
|
+
mattr_accessor :token_signature_key, default: -> {Rails.application.secret_key_base}
|
8
|
+
|
9
|
+
def self.user_class
|
10
|
+
return @@user_class.constantize
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.setup
|
14
|
+
yield self
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails_jwt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Muhammad Aamir
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-03-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: jwt
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.2.2
|
41
|
+
description: This gem makes it super easy to add JWT support in your Rails project.
|
42
|
+
Just a few of quick steps and you are good to go!
|
43
|
+
email:
|
44
|
+
- mail@aamir.pk
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- MIT-LICENSE
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- app/controllers/rails_jwt/application_controller.rb
|
53
|
+
- app/controllers/rails_jwt/authentication.rb
|
54
|
+
- app/controllers/rails_jwt/login_controller.rb
|
55
|
+
- app/jobs/rails_jwt/application_job.rb
|
56
|
+
- app/mailers/rails_jwt/application_mailer.rb
|
57
|
+
- app/models/rails_jwt/application_record.rb
|
58
|
+
- config/routes.rb
|
59
|
+
- lib/generators/rails_jwt/install/install_generator.rb
|
60
|
+
- lib/generators/rails_jwt/install/templates/rails_jwt.rb
|
61
|
+
- lib/rails_jwt.rb
|
62
|
+
- lib/rails_jwt/engine.rb
|
63
|
+
- lib/rails_jwt/version.rb
|
64
|
+
- lib/tasks/rails_jwt_tasks.rake
|
65
|
+
homepage: https://github.com/aamir-pk/rails_jwt
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubygems_version: 3.0.6
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Super easy way to add JWT support for Rails API projects.
|
88
|
+
test_files: []
|