Rails User Authentication with Devise and simple_token_authentication
Devise is a greate and well known ruby gem for user authentication(sign_in and sign_up purposes normally) but token authentication support has been removed from Devise for security reasons. Another gem (simple_token_authentication) can be used for this purpose. Let’s starts.
Setup our project
First, create new rails api app
rails new rails-api --api
And add two new gems at Gemfile
gem "devise"
gem "simple_token_authentication"
Install new gems
bundle install
Install devise and Generate new model by Devise — I will call it User
rails g devise:install
rails generate devise User
rails db:migrate
Add authentication_token
column into User
table by creating migration field.
rails g migration add_authentication_token_to_users "authentication_token:string{30}:uniq"
Now run
rails db:migrate
Define which model will be token authenticatable. In this case, it’s User
model. Add acts_as_token_authenticatable
at user.rb
file.
class User < ActiveRecord::Base
acts_as_token_authenticatable
end
Finally define which controllers will handle token authentication i.e application_controller.rb
class ApplicationController < ActionController::API
acts_as_token_authentication_handler_for User
end
Route for API
Rails.application.routes.draw do
devise_for :users
namespace :api, defaults: {format: :json} do
namespace :v1 do
devise_scope :user do
post "sign_up", to: "registrations#create"
post "sign_in", to: "sessions#create"
end
end
end
end
So basically, after enter rails routes
on terminal, we will have: (Our URL will be like http://localhost:3000/api/v1/sign_up
)
- Sign Up:
http://localhost:3000/api/v1/sign_up
- Sign In:
http://localhost:3000/api/v1/sign_in
Sign Up
First, create new folder app/controllers/api/v1
(v1 is version one of Api. Because in the future may be we will have v2 or v3…)
And now create new controller named registrations_controller.rb
Test with Postman
You can download Postman here.
We will create a POST request to localhost:3000/api/v1/sign_up
with passing parameters in body as JSON object like this.
{
"user": {
"email":"abc@example.com",
"password":"password",
"password_confirmation":"password"
}
}
The server will return user’s information if your params are correct.
Ok looks good. Let’s move to Sign In.
Sign In
Basically, when user sign in, we will create new session for that user. So, create new controller named sessions_controller.rb
under app/controller/v1
folder.
Test with Postman
You can download Postman here.
We will create a POST request to localhost:3000/api/v1/sign_in
with passing parameters in body as JSON object like this.
{
"user": {
"email":"abc@example.com",
"password":"password"
}
}
And what’s happen if you try to sign in with wrong password ? Of course you will get 401-Unauthorized error!
Now suppose you’ve another model, say Posts, and you want your application to restrict users from accessing any of the Posts controller action from unauthorized users, put this line in your posts_controller.rb as a very first line in this class.
before_action :authenticate_user!
This will restrict all actions, in this controller, to only those users who’re currently signed in.
before_action :authenticate_user!, except: [:create]
This will restrict all actions of this controller,except create action, to only those users who’re currently signed in.
before_action :authenticate_user!, only: [:create]
This will restrict create action to only those users who’re currently signed in.