rails_jwt 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,5 @@
1
+ module RailsJwt
2
+ class ApplicationController < ActionController::API
3
+ # protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -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
@@ -0,0 +1,4 @@
1
+ module RailsJwt
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module RailsJwt
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module RailsJwt
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ RailsJwt::Engine.routes.draw do
2
+ post 'login', to: 'login#login'
3
+ end
@@ -0,0 +1,7 @@
1
+ class RailsJwt::InstallGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('templates', __dir__)
3
+
4
+ def generate_config_file
5
+ copy_file "rails_jwt.rb", "config/initializers/rails_jwt.rb"
6
+ end
7
+ end
@@ -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
@@ -0,0 +1,6 @@
1
+ module RailsJwt
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace RailsJwt
4
+ config.generators.api_only = true
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module RailsJwt
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :rails_jwt do
3
+ # # Task goes here
4
+ # 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: []