I’m going to give you detailed steps on how to get knock gem up and running in your Rails application. The idea for this article stems from the fact that I couldn’t find a well-defined and up-to-date resource on how to implement a Rails API token authentication. For this tutorial, I will be using the latest version (6.0) of Ruby on Rails.


Set-Up

First things first, let’s generate a new Rails app:

$ rails new JWTapp — api -d=postgresql -T
$ cd JWTapp
$ rails db:create
$ rails db:migrate

CORS

Let’s uncomment Cors gem to permit access to the API:

gem ‘rack-cors’
$ bundle install

Write the following in cors.rb :

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
 allow do
    origins ‘http://localhost:3000'
    resource ‘*’,
    headers: :any,
    methods: [:get, :post, :put, :patch, :delete, :options, :head]
 end
end

Bcrypt & Knock Gem

Bcrypt is a hash algorithm for password hashing and Knock, which is mainly for JWT authentication.

gem ‘bcrypt’
gem ‘knock’

Let’s run:

$ bundle install

User model and controllers

Now, we are going to create a user using the scaffold generator.

$ rails generate scaffold User username:string email:string password_digest:string

Include this in your user model.

# app/models/user.rb 

class User < ApplicationRecord
   has_secure_password
   validates :username, presence: true
   VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.freeze
   validates :email, presence: true,uniqueness: true, format: { with: VALID_EMAIL_REGEX }
end

The user controller generated by the scaffold gave us a field called password_digest. But Bcrypt, in addition to hashing the password, also turns password_digest into two fields, password and password_confirmation. So we need to change the permitted params from password_digest to these two fields.

# app/controllers/users_controller.rb

def user_params
 params.permit(:username, :email, :password, :password_confirmation)
end

Let’s remove the ‘location: @user’ in the create method.

# app/controllers/users_controller.rb

def create
   @user = User.new(user_params)
if @user.save
     render json: @user, status: :created
   else
     render json: @user.errors, status: :unprocessable_entity
   end
 end

Migrate data by running.

$ rails db:migrate

Let’s create a user using the rails console.

$ rails c

User.create(username: “Danny”, email: “dan@ymail.com”, password: “enemona”, password_confirmation: “enemona”)

#web-development #user-authentication #programming #api #ruby-on-rails

Knock as an Authentication Solution for Your Rails API
1.40 GEEK