JWT is a Json Web Token,It is a standard and has been implemented in
almost all popular programming languages. Hence, they can be easily used
or exchanged in systems implemented in diverse platforms.
JWT has libraries for almost all platforms and Ruby is no exception.
Now we will see how JWT is used in Rails:
We will create a simple Rails application which uses the excellent Devise gem for authentication and the jwt gem for creating and verifying JWT tokens.
Let’s create a sample Rails application :
Create home_controller.rb in the app/controllers
Now let’s create the Devise configuration files:
For that we have will have to create the Devise User model and migrate the database:
In app/controllers/application_controller.rb:
Now we have to update our routes.rb to add the authentication endpoint.
JWT has libraries for almost all platforms and Ruby is no exception.
Now we will see how JWT is used in Rails:
We will create a simple Rails application which uses the excellent Devise gem for authentication and the jwt gem for creating and verifying JWT tokens.
Let’s create a sample Rails application :
rails new rails_on_jwtOnce the application is generated, create a Home controller which we will use to check our authentication.
Create home_controller.rb in the app/controllers
classHomeController ApplicationController def index end endWrite the route for HomeController to /home in config/routes.rb:
Rails.application.routes.draw do get 'home' => 'home#index' endNow, add Devise to our application. First, we will add the Devise and jwt gems in our Gemfile.
gem 'devise' gem 'jwt'Then run a command “bundle install” on terminal.
Now let’s create the Devise configuration files:
For that we have will have to create the Devise User model and migrate the database:
rails g devise User rakedb:migrateCreated User Model use for authentication.now It’s time to integrate jwt into our application. First, we will create a class named JsonWebToken in lib/json_web_token.rb.This class will encapsulate the JWT token encoding and decoding logic.
classJsonWebToken defself.encode(payload) JWT.encode(payload, Rails.application.secrets.secret_key_base) end defself.decode(token) returnHashWithIndifferentAccess.new(JWT.decode(token, Rails.application.secrets.secret_key_base)[0]) rescue nil end endWe have to create an initializer for including the JsonWebToken class in config/initializers/jwt.rb.
require 'json_web_token'We have to add some helper method in ApplicationController class which we will use in AuthenticationController class:
In app/controllers/application_controller.rb:
classApplicationController
<ActionController::Base
attr_reader :current_user
protected
defauthenticate_request!
unlessuser_id_in_token?
renderjson: { errors: ['Not Authenticated'] }, status: :unauthorized
return
end
@current_user = User.find(auth_token[:user_id])
rescue JWT::VerificationError, JWT::DecodeError
renderjson: { errors: ['Not Authenticated'] }, status: :unauthorized
end
private
defhttp_token
@http_token ||= if request.headers['Authorization'].present?
request.headers['Authorization'].split(' ').last
end
end
defauth_token
@auth_token ||= JsonWebToken.decode(http_token)
end
defuser_id_in_token?
http_token&&auth_token&&auth_token[:user_id].to_i
end
end
We have added a few helper methods like authenticate_request!which
will act as a before_filter to check user credentials and we have
created AuthenticationController to handle all authentication requests
to the API. In app/controllers/authentication_controller.rb:classAuthenticationController<ApplicationController
defauthenticate_user
user = User.find_for_database_authentication(email: params[:email])
ifuser.valid_password?(params[:password])
renderjson: payload(user)
else
renderjson: {errors: ['Invalid Username/Password']}, status: :unauthorized
end
end
private
def payload(user)
return nil unless user and user.id
{
auth_token: JsonWebToken.encode({user_id: user.id}),
user: {id: user.id, email: user.email}
}
end
end
Here we have added AuthenticationController to implement the
authentication endpoint. It uses Devise to authenticate the user and
issue a JWT if the credentials are valid.Now we have to update our routes.rb to add the authentication endpoint.
Rails.application.routes.draw do post 'auth_user' => 'authentication#authenticate_user' get 'home' => 'home#index' endAlso, we have to modify the HomeController to secure it using a before_filter and add a meaningful response in case of successful authentication:
classHomeController<ApplicationController
before_filter :authenticate_request!
def index
renderjson: {'logged_in' => true}
end
end
Now, create a sample user to test the authentication by using rails
console or by Using Seed command:Start the server and check out how JWT
authentication works:rails s
Source: http://www.cryptextechnologies.com/blogs/using-jwt-in-rails
Comments
Post a Comment