At Agira, Technology Simplified, Innovation Delivered, and Empowering Business is what we are passionate about. We always strive to build solutions that boost your productivity.

, ,

Authenticating Rails Web Services With JWT

  • By Saravana
  • August 30, 2018
  • 1050 Views

This blog will help you to set up simple JWT authentication solution for your Rails API. However, i have implemented many authentication solutions in our projects, but i personally felt that JWT is best and secured web token and that provides an easy way to handle the information shared between the client and server. On this blog, let’s see how we can implement JWT for authentication and to transfer information between resources.

What Is JWT?

JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for creating access tokens.
JWT consists of three parts and its basically separated by dots,

  • Header
  • Payload
  • Signature

Header – Header is the first part of the JWT token, It consists of two things, One is the type of algorithm used to generate signature and second is the type of token.
Payload – Payload is the second part of the JWT token. It consists of information about the entity.
Signature – Payload is the third part of the JWT token, It is calculated by base64url encoding the header and payload.

How to implement JWT in Rails application?

 

Step: 1 – First create a new rails application

rails new app

 

Step: 2 – Add the jwt gem into Gemfile.

gem 'jwt'

 

Also Read: Caching In Ruby On Rails 5.2

 

Step: 3 – Create JWT service file

Create JsonWebToken class under lib/json_web_token.rb file. This will be used to create and validate the jwt token.
JsonWebToken’s encode method is used to create JWT token by using payload and secret key.
JsonWebToken’s decode method is used to decode the token to convert payload using secret key.

class JsonWebToken
def self.encode(payload)
JWT.encode(payload, ENV["SECRET_KEY_BASE"])
end
def self.decode(token)
return HashWithIndifferentAccess.new(JWT.decode(token, ENV["SECRET_KEY_BASE"])[0])
rescue
nil
end
end

 

Step: 3 – Create users and jwt_tokens table.

Here the below tables used to handle user and session tokens.
users – Used to store user details and login information.

create_table "users" do |t|
t.string "first_name"
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "api_key", null: false
end

Jwt_tokens – Used to store the sessions details and jwt tokens.

create_table "jwt_tokens" do |t|
t.bigint "user_id"
t.string "token"
end

 

Related: 10 Useful Ruby On Rails Gems We Couldn’t Live Without

 

Step: 4 – Create a rails model for above tables

 

1. Add User under app/models/user.rb

Each users will have unique API_KEY, also each user will have many jwt tokens. Usually, these JWT tokens are stored in jwt_tokens table.

class User < ApplicationRecord
# Validations
validates :first_name, :last_name, :email, presence: true
validates :email, uniqueness: true
# associations
has_many :jwt_tokens
def assign_api_key
self.api_key = SecureRandom.uuid
end
end

 

2. Add JwtToken under app/models/jwt_token.rb

 

class JwtToken < ApplicationRecord
belongs_to :user
end

 

Step: 5 – Create sessions API to create JWT

In sessions, API validates the user authentication, and it will create the jwt token using JsonWebToken class. JWT token will be stored in a jwt_tokens table along with api_key. These tokens will be used to verify the further requests.

# sessions controller
require 'json_web_token'
class SessionsController < Devise::SessionsController
    def create
        user = User.find_for_database_authentication(email: params[:user][:email])
            if user && user.valid_password?(params[:user][:password])
                render json: payload(user, params)
            else
                render json: {success: false, message: 'Invalid details' }, status: :unauthorized
            end
    end
    private
        def payload(user, params = {})
            jwt_token = user.jwt_tokens.create(token: SecureRandom.uuid)
  	{
    	    api_key: user.api_key,
    	    auth_token: JsonWebToken.encode({token: jwt_token.token})
  	}
        end
end

 

Step: 6 – Create User details API to use JWT token as a session token

In user details API the jwt token is passed through headers, and the tokens are decoded using JsonWebToken class. The decoded token is validated against the stored token and this is how the session will be maintained between client and server.

# users controller
require 'json_web_token'
class UsersController < Devise::SessionsController
    # validate the session using JWT token
    before_action :authenticate_request!
    def show
        render json: { success: true, user: @user }
    end
    def authenticate_request!
        token = JsonWebToken.decode(request.headers['Authorization'])
        @user = User.joins(:jwt_tokens).where('jwt_tokens.token =?', token).last
        render json: { error: 'You are not authorized' }, status: :401 unless token || @user
    end
end

So far i have covered the process of creating sessions using JWT and also the procedure of handling sessions. Hopefully you can use JWT for creating secured tokens to protect your web services.
Hope this helps you! Similarly you can learn more on interesting on latest technologies, never miss out anything from our largest blog portal where you can get continuous blog updates & latest posts about all the latest technologies which would be perfect for your 15 minutes tea break! In case if you’re a newbie then don’t forget to subscribe us to get the latest updates from diverse technologies. What else guys hit the subscribe link and go crazy over learning.
For more inquires reach us via info@agiratech.com

Saravana

An enthusiastic Tech Lead with 7 plus years of experience in Web development arena. Owns legitimate experience in Ruby, Ruby On Rails, AngularJs, DevOps. Golang, Another add on, This young tech freak never miss a chance to get his hands on planting and Gardening even in his busy weekends.