Riski Midi Wardana
Nov 17, 2018 · 4 min read

What we need

  • Ruby 2.5.1
  • Rails 5.2.1
  • Postgresql
  • Insomnia / Postman

Github Repository

https://github.com/riskimidiw/rails-jwt

REST API table

Okay now we’re ready to generate rails project, type this on your terminal

$ rails new rails-jwt --api

Add Json Web Token (jwt) and bcrypt gem

  • JWT : Token encoder / decoder with expiration time
  • bcrypt : Password encryption
# Use Json Web Token (JWT) for token based authentication
gem 'jwt'
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'

and then install dependencies by typing this on your terminal

$ bundle install

Update routes

# config/routes.rbRails.application.routes.draw do
resources :users, param: :_username
post '/auth/login', to: 'authentication#login'
get '/*a', to: 'application#not_found'
end

In the routes.rb, we defined routes for users using resources. resources syntax help us for generating REST API pattern path for user using _username as parameter. So it will looks like our REST API table above.

Create JsonWebToken class

app/lib/json_web_token.rb

SECRET_KEY is the key for encoding and decoding token. In the code above, we assign secret key that generated by default by rails application into SECRET_KEY variable. SECRET_KEY must be secret and not to be shared. Everytime we’re doing some encoding and decoding using JWT, we need to specify the SECRET_KEY. By grouping and encapsulating JWT encoding and decoding mechanism in this class, we will reduce couple of code that have responsibility for doing encoding and decoding job, because we don’t need to specify SECRET_KEY everytime. Decode and encode function above defined as static function because it will give a flexibility for doing encoding and decoding job without instantiate JsonWebToken object.

self.encode function has 2 parameters. first payload and second exp. payload is key-value object for holding data that want to be encoded. exp stand for expiration for holding expiration time token. if exp not specified it will give you default value in 24 hour or one day.

In self.decode function we decoded the token that given by user and get the first value then assign to decoded variable, the first value contain payload that we had already encoded before and second value contain information about algorithm that we use for encoding and decoding token.

Create authorize_request function

app/controllers/application_controller.rb

authorize_request function has responsibility for authorizing user request. first we need to get token in header with ‘Authorization’ as key. with this token now we can decode and get the payload value. in this application we define user_id in payload. You should not include the user credentials data into payload because it will cause security issue, you can include data that needed to authorizing user. When performing JsonWebToken.decode function, it will return JWT::DecodeError if there was an error like token was expired, token not valid, token missing etc. After we got user_id from payload then we will try to find user by id and assign it into current_user variable, If user not exist it will return ActiveRecord::RecordNotFound and it will render error message with http status unauthorized.

Create user model

$ rails g model user name:string username:string email:string password_digest:string

add user validation

app/models/user.rb

Create user controller

$ rails g controller users

Add Create, Read, Update, Delete (CRUD ) functionality

app/controllers/users_controller.rb

Create authentication controller

$ rails g controller authentication

Implement login feature

app/controllers/authentication_controller.rb

In JWT there is no way to invalidate token, you can use one of this approach to implement logout feature :

1. Remove token from client, but token still valid, in my opinion you should use short time period token.
2. Add token into blacklist, when token added into blacklist token still valid until expiration time but you can deny this request from accessing resource.

Now you can test your application response with insomnia or postman

Create User
Login
Get All Users
Get User

Binar Academy

Endless knowledge sharing, from our internal Masters, Graduates, and Talent Pool. Enroll to our academy www.binar.co.id

Riski Midi Wardana

Written by

Binar Academy

Endless knowledge sharing, from our internal Masters, Graduates, and Talent Pool. Enroll to our academy www.binar.co.id

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade