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