Using Devise in Rails 5.1 Api Webapp for Login Feature

Step 1

Add devise gem:

gem 'devise'

to Gemfile.

Step 2

Run

bundle

to install the gem.

Step 3

Run the Devise generator:

rails generate devise:install

Step 4

Configure the action mailer host and port in config/environments/development.rb:

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

In production, :host should be set to the actual host of your application.

Step 5

Create the user model.

rails generate devise user

Step 6

In routes.rb, remove :

devise_for :users 

and add:

resources :sessions, only: [:create, :destroy]

Step 7

In user model, add:

:confirmable

Step 8

We need confirm the email feature that sends email confirmation to cofirm the email when the user signs up. So, uncomment:

   t.string   :confirmation_token
   t.datetime :confirmed_at
   t.datetime :confirmation_sent_at
   t.string   :unconfirmed_email # Only if using reconfirmable

in the migration file for users.

Step 9

Uncomment:

add_index :users, :confirmation_token,   unique: true

in the migration file for users.

Step 10

Create the sessions controller.

rails g controller sessions create destroy

Delete the generated routes in routes.rb:

  get 'sessions/create'
  get 'sessions/destroy'

Step 11

Migrate the database.

rails db:migrate

Step 12

Implement the create action in sessions controller:

  def create
    user = User.where(email: params[:email]).first

    if user&.user.valid_password?(params[:password])
      render json: user.as_json(only: [:id, :email]), status: :created  
    else
      head :unauthorized
    end
  end

Step 13

In rails console, create a user with a password:

User.create(email: 'bugs@rubyplus.com', password: 'welcome')

Step 14

Simulate login using Curl command:

curl -X POST --data "email=bugs@rubyplus.com&password=welcome" http://localhost:3000/sessions

Response:

{"id":1,"email":"bugs@rubyplus.com"}

In the log file, you can see the status code:

Completed 201 Created in 140ms 

For failed login:

curl -X POST --data "email=bugs@rubyplus.com&password=notwelcome" http://localhost:3000/sessions

Response:

None

You can see:

Completed 401 Unauthorized in 125ms (ActiveRecord: 0.3ms)

in the log file.

Step 15

Refactor. Move the login logic into the user model.

  def self.valid_login?(email, password)
    user = where(email: email).first
    [user&.valid_password?(password), user]
  end

The create action becomes:

  def create
    success, user = User.valid_login?(params[:email], params[:password])
    if success
      render json: user.as_json(only: [:id, :email]), status: :created  
    else
      head :unauthorized
    end
  end

In this article, you learned how to use devise to implement login functionality in a Rails 5.1 api only application.


Related Articles


Create your own user feedback survey