jwt-rails 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f6d25580486b96a786e98b4b0856526101e13451b66950f2980d6484b1dca293
4
+ data.tar.gz: 344c2bb6bcf75e9757d0b51afe6973c1f65aaba44a493427565ebe559052fae4
5
+ SHA512:
6
+ metadata.gz: d427d22c40a1d1bb1e54ec1b00e2a0e7d13ad3f72a6faf79d6f90265518496bae6bdc58dd1d87477060e2130a541d36fed48a85768b1ee1e0e131fe32d3c5e92
7
+ data.tar.gz: 0dc9820ed2b37cb22dac5253104c675831080a7fa0889b11c3ad6f1f04c14541cd563ef76c4fc7320d771ee495302c6ecfae36457692abe3a0d14896895fd042
@@ -0,0 +1,106 @@
1
+ # README
2
+ jwt-rails project developed for helping Authenticate your rails rest-api project<br/>
3
+ you can fast develop project with jwt-rails<br/>
4
+ I used reference following websites<br/>
5
+ https://guides.rubyonrails.org/generators.html#creating-generators-with-generators <br/>
6
+ https://medium.com/binar-academy/rails-api-jwt-authentication-a04503ea3248 <br/>
7
+
8
+ ## Require
9
+ * rails api only project ```rails new my_api --api``` https://guides.rubyonrails.org/api_app.html
10
+ * You don't have User Model, It will generate User Model
11
+ * 'rails', '~> 3.2.0'
12
+
13
+ ## Getting Started
14
+ 1. Add gem in Gemfile
15
+ ```yaml
16
+ gem 'jwt-rails', '~> 0.0.1'
17
+ ```
18
+ OR
19
+ ```yaml
20
+ gem 'jwt-rails', :git => "git://github.com/x1wins/jwt-rails.git"
21
+ ```
22
+
23
+ 2. Generate JWT class, User Model, Endpoint
24
+ ```bash
25
+ rails generate jwt_rails
26
+ rake db:migrate
27
+ ```
28
+
29
+ 3. Endpoint
30
+ 1. Create User
31
+ ```bash
32
+ curl -d '{"user": {"name":"ChangWoo", "username":"helloworld", "email":"x1wins@changwoo.org", "password":"hello1234", "password_confirmation":"hello1234"}}' -H "Content-Type: application/json" -X POST -i http://localhost:3000/users
33
+ ```
34
+ 2. Login
35
+ ```bash
36
+ curl -d '{"email":"x1wins@changwoo.org", "password":"hello1234"}' -H "Content-Type: application/json" -X POST http://localhost:3000/auth/login | jq
37
+ {
38
+ "token": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NzcyMjkwOTl9.an-cp7gWzEuufwvWPo3SFXzpxL_G1wvNpm6g7W_gdQU",
39
+ "exp": "12-24-2019 15:11",
40
+ "username": "helloworld"
41
+ }
42
+ ```
43
+ 3. Token Usage <br/>
44
+ If you have Post scaffold. you can use following curl command
45
+ 1. Fail Case - Wrong token
46
+ ```bash
47
+ curl -X GET -i http://localhost:3000/posts
48
+ HTTP/1.1 401 Unauthorized
49
+ ```
50
+ 2. Success Case
51
+ ```bash
52
+ curl -X GET -i http://localhost:3000/posts -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NzcyMjkwOTl9.an-cp7gWzEuufwvWPo3SFXzpxL_G1wvNpm6g7W_gdQU"
53
+ HTTP/1.1 200 OK
54
+ ```
55
+
56
+ 4. Scaffold Example
57
+ 1. Use ```user:references``` in scaffold code
58
+ ```bash
59
+ rails g scaffold post body:string user:references published:boolean
60
+ ```
61
+ 2. Authenticate <br/>
62
+ Insert ```before_action :authorize_request``` code into Controller
63
+ ```ruby
64
+ class PostsController < ApplicationController
65
+ before_action :authorize_request
66
+
67
+ //...other code
68
+
69
+ end
70
+ ```
71
+ 3. Authorize <br/>
72
+ https://stackoverflow.com/questions/17594939/check-if-current-user-is-the-owner-of-a-resource-and-allow-edit-delete-actions/57279448#57279448 <br/>
73
+ 1. Insert ```is_owner_object``` code into Controller <br/>
74
+ 2. Append ```merge(user_id: @current_user.id)``` to post_params method
75
+ ```ruby
76
+ class PostsController < ApplicationController
77
+ before_action :authorize_request
78
+ before_action :set_post, only: [:show, :update, :destroy]
79
+ before_action only: [:edit, :update, :destroy] do
80
+ is_owner_object @post ##your object
81
+ end
82
+
83
+ //...other code
84
+
85
+ def post_params
86
+ params.require(:post).permit(:body).merge(user_id: @current_user.id)
87
+ end
88
+ end
89
+ ```
90
+ 4. Test with CURL
91
+ 1. Create
92
+ ```bash
93
+ curl -X POST -i http://localhost:3000/posts -d '{"post": {"body":"sample body text sample"}}' -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NzcyMzY1NTJ9.0pRv-wnQPdQd1WoaA5mSPDWagfGCk---kwO7pSmKkUg"
94
+ ```
95
+ 2. Index
96
+ ```bash
97
+ curl -X GET -i http://localhost:3000/posts -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NzcyMzY1NTJ9.0pRv-wnQPdQd1WoaA5mSPDWagfGCk---kwO7pSmKkUg"
98
+ ```
99
+
100
+
101
+ ## Contribute
102
+ How to build gem
103
+ ```bash
104
+ gem build jwt-rails.gemspec
105
+ gem install jwt-rails-0.0.1.gem
106
+ ```
@@ -0,0 +1,8 @@
1
+ Description:
2
+ JWT, user resource for Auth rest api generator
3
+
4
+ Example:
5
+ rails generate jwt_rails
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,27 @@
1
+ class JwtRailsGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('templates', __dir__)
3
+
4
+ def copy_jwt_rails_file
5
+ # Use Json Web Token (JWT) for token based authentication
6
+ gem 'jwt'
7
+ # Use ActiveModel has_secure_password
8
+ gem 'bcrypt', '~> 3.1.7'
9
+
10
+ route "resources :users, param: :_username"
11
+ route "post '/auth/login', to: 'authentication#login'"
12
+ route "get '/*a', to: 'application#not_found'"
13
+
14
+ copy_file "json_web_token.rb", "lib/json_web_token.rb"
15
+ copy_file "application_controller.rb", "app/controllers/application_controller.rb"
16
+
17
+ generate "model", "user name:string username:string email:string password_digest:string"
18
+ copy_file "user.rb", "app/models/user.rb"
19
+ generate "controller", "users"
20
+ copy_file "users_controller.rb", "app/controllers/users_controller.rb"
21
+ generate "controller", "authentication"
22
+ copy_file "authentication_controller.rb", "app/controllers/authentication_controller.rb"
23
+
24
+ puts "Genenrate Finish"
25
+ end
26
+
27
+ end
@@ -0,0 +1,37 @@
1
+ require 'json_web_token'
2
+
3
+ class ApplicationController < ActionController::API
4
+
5
+ def not_found
6
+ render json: { error: 'not_found' }
7
+ end
8
+
9
+ def authorize_request
10
+ header = request.headers['Authorization']
11
+ header = header.split(' ').last if header
12
+ begin
13
+ @decoded = JsonWebToken.decode(header)
14
+ @current_user = User.find(@decoded[:user_id])
15
+ rescue ActiveRecord::RecordNotFound => e
16
+ render json: { errors: e.message }, status: :unauthorized
17
+ rescue JWT::DecodeError => e
18
+ render json: { errors: e.message }, status: :unauthorized
19
+ end
20
+ end
21
+
22
+ def is_owner user_id
23
+ unless user_id == current_user.id
24
+ render json: nil, status: :forbidden
25
+ return
26
+ end
27
+ end
28
+
29
+ def is_owner_object data
30
+ if data.nil? or data.user_id.nil?
31
+ return render status: :not_found
32
+ else
33
+ is_owner data.user_id
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,22 @@
1
+ class AuthenticationController < ApplicationController
2
+ before_action :authorize_request, except: :login
3
+
4
+ # POST /auth/login
5
+ def login
6
+ @user = User.find_by_email(params[:email])
7
+ if @user&.authenticate(params[:password])
8
+ token = JsonWebToken.encode(user_id: @user.id)
9
+ time = Time.now + 24.hours.to_i
10
+ render json: { token: token, exp: time.strftime("%m-%d-%Y %H:%M"),
11
+ username: @user.username }, status: :ok
12
+ else
13
+ render json: { error: 'unauthorized' }, status: :unauthorized
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def login_params
20
+ params.permit(:email, :password)
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ class JsonWebToken
2
+ SECRET_KEY = Rails.application.secrets.secret_key_base.to_s
3
+
4
+ def self.encode(payload, exp = 24.hours.from_now)
5
+ payload[:exp] = exp.to_i
6
+ JWT.encode(payload, SECRET_KEY)
7
+ end
8
+
9
+ def self.decode(token)
10
+ decoded = JWT.decode(token, SECRET_KEY)[0]
11
+ HashWithIndifferentAccess.new decoded
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ class User < ApplicationRecord
2
+ has_secure_password
3
+ validates :email, presence: true, uniqueness: true
4
+ validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
5
+ validates :username, presence: true, uniqueness: true
6
+ validates :password,
7
+ length: { minimum: 6 },
8
+ if: -> { new_record? || !password.nil? }
9
+ end
@@ -0,0 +1,54 @@
1
+ class UsersController < ApplicationController
2
+ before_action :authorize_request, except: :create
3
+ before_action :find_user, except: %i[create index]
4
+ before_action only: [:show, :update, :destroy] do
5
+ is_owner_object @user ##your object
6
+ end
7
+
8
+ # GET /users
9
+ def index
10
+ @users = User.all
11
+ render json: @users, status: :ok
12
+ end
13
+
14
+ # GET /users/{username}
15
+ def show
16
+ render json: @user, status: :ok
17
+ end
18
+
19
+ # POST /users
20
+ def create
21
+ @user = User.new(user_params)
22
+ if @user.save
23
+ render json: @user, status: :created
24
+ else
25
+ render json: { errors: @user.errors.full_messages },
26
+ status: :unprocessable_entity
27
+ end
28
+ end
29
+
30
+ # PUT /users/{username}
31
+ def update
32
+ unless @user.update(user_params)
33
+ render json: { errors: @user.errors.full_messages },
34
+ status: :unprocessable_entity
35
+ end
36
+ end
37
+
38
+ # DELETE /users/{username}
39
+ def destroy
40
+ @user.destroy
41
+ end
42
+
43
+ private
44
+
45
+ def find_user
46
+ @user = User.find_by_username!(params[:_username])
47
+ rescue ActiveRecord::RecordNotFound
48
+ render json: { errors: 'User not found' }, status: :not_found
49
+ end
50
+
51
+ def user_params
52
+ params.require(:user).permit(:name, :username, :email, :password, :password_confirmation)
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jwt-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chang-Woo Rhee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-12-23 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: 3.2.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.2.0
27
+ description: Generate JWT, User model, controller
28
+ email: x1wins@changwoo.net
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - lib/generators/jwt_rails/USAGE
35
+ - lib/generators/jwt_rails/jwt_rails_generator.rb
36
+ - lib/generators/jwt_rails/templates/application_controller.rb
37
+ - lib/generators/jwt_rails/templates/authentication_controller.rb
38
+ - lib/generators/jwt_rails/templates/json_web_token.rb
39
+ - lib/generators/jwt_rails/templates/user.rb
40
+ - lib/generators/jwt_rails/templates/users_controller.rb
41
+ homepage: https://github.com/x1wins/jwt-rails
42
+ licenses:
43
+ - MIT
44
+ metadata:
45
+ homepage_uri: https://www.changwoo.org
46
+ source_code_uri: https://github.com/x1wins/jwt-rails
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.1.1
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: JWT, user resource for Auth rest api generator
66
+ test_files: []