jwt-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []