DEV Community

Cover image for How to Create User Authentication in a Ruby on Rails API
Kyle Petersen
Kyle Petersen

Posted on

How to Create User Authentication in a Ruby on Rails API

Introduction

Ruby on Rails, for many years now, has been an extremely popular and influential framework that allows a developer to quickly and cost-effectively build and deploy fully functioning backends. With that in mind, in nearly every complex web application the problem of user authentication will most definitely come into play. This guide will attempt to explain how you can quickly build secure authentication for your web application with Ruby on Rails.

Installation

Make sure the below items are installed on your machine before we begin.

Creating our project

Just like how we would normally create any Ruby on Rails project, we are going to run rails new <name of project> --api. We are then going to need to change a few things in the gem file. Within the file "Gemfile" on line 17 there should be a commented line which reads gem 'bcrypt', '~> 3.1.7' or something similar. Un-comment it out and add the line gem 'jwt' below as well. It should then end up looking something like this.

Alt Text
After both are added run the command bundle install to add both the gems to your project.

Creating our User model

Next, we are going to create our user model in which we are going to be using to authenticate. From our terminal, we are going to run rails g scaffold User username:uniq password:digest. It is important to note that the digest at the end of password:digest means that the user's password will not be stored as plain text within our database and adds a few extra goodies to our project. After our model has completed we are going to migrate our database using the command rails db:migrate. After our migration we need to add the lines validates :email, presence: true, uniqueness: true to the user.rb file within our models folder. This makes sure that when a new user is created that the username is unique within the database.

Alt Text

Application Controller

We are now going to create our Authenticate method from within our application controller file so any of our other controllers can access it when needed. Creating an empty method, our file should look like this.

Alt Text

The first thing we are going to check within our method is whether authorization headers were sent. To do that we can create a small if statement.

Alt Text

After we check whether the auth header was sent, we can then begin to decode our JWT token that should have been sent within the auth header. We should wrap the next few things within a begin rescue block of code which works similarly to a try-catch in other languages.

Alt Text

Within our begin/ rescue block, we should then decode our JWT token, find our payload, and get our user_id so we can then find our User within our database. To do this we will create a method named secret and token.

Our secret method will find a key within a secret key base which we can access like so.

Alt Text

We can then create our Token method which will access the second item within the auth_headers array.

Alt Text

Afterward, those two methods are created we can finish our Authorize method. All we need to do is get the user_id from our payload and then use that to find our authorized user.

Alt Text

For future application, we are going to add one last method to our application_controller which will be our create_token method.

Alt Text

The last thing we need within our Application controller class, for now, is to specify ours before action. All we are going to say here is that before anything else is attempted within our application controller we must authenticate first. to do that all we need to do is add before_action :authenticate

In the end, our application_controller.rb file should look like this.

Alt Text

User Controller

Since our authentication controller is finished we will also want to make a change to our User controller. Specifically, we need to create a token whenever a new user is created. To do this we can use the create_token method we had made earlier within our create method like so.

Alt Text

Authentication Controller

For someone who is not creating a user for the first time, we need to create a login method. We will do this in a controller called AUthentication Controller. To create this controller rin rails g controller authentication. A new file should then exist with your controller folder name authentication_controller.rb. Within this file, there should only be an empty class named AuthenticationController.

Alt Text

Within here we will then create our login method and make sure that it skips our authenticate method we had created earlier.

Alt Text

Within our method, we must first find our specific user using ruby's find_by method and then authenticate that user once found with our authenticate method we had created in our application_controller.

Alt Text

After we authenticate our user. We can then use the methods we had created earlier within our application controller to make a new JWT token for the user and also send all of the user data as JSON with the render method.

In the end, our authentication_controller.rb file should look like so.

Alt Text

Routes

The final step before we are finished with our fully functioning user authentication is to specify our login route. From within routs.rb which is located within the config controller, add post 'login', to: 'authentication#login' which should send any /login request directly to our login method. The file should end up looking something like this.

Alt Text

Top comments (3)

Collapse
 
eminarium profile image
Merdan Durdyyev

Step by step description of the process. Very good Kyle. All the bits and bytes of jwt user authentication with Rails.

Collapse
 
benedicttt profile image
Сергей Киевский

this not work: @user.authenticate - what is it method?
request.headers['Authorization'] - why need this method if the equal nil?

Collapse
 
benedicttt profile image
Сергей Киевский

what is it auth_header method?