The Basics of Login

Introduction

In this article I will be going over the basics of setting up login for a web application, using a Rails API, and testing it throughout using Postman. I will begin by giving a brief overview of my initail setup and creating a test user. Then I go into creating a controller to handle login and how to create a custom route for it. From there I will explain how we can use Postman to test our endpoints to figure out how to fill out our login method and what we can expect to get back at this stage on a correct login attempt.

Step I: Initial Setup

In this section I am going to quickly go over the set up of the backend of this project.

To start, I created a rails api using postgresql as my database. I generated a user model and migration file with two attributes: a username and password_digest. I am using a digest because it will be an encrypted version of the password to a database as opposed to the string a user entered. Inside the gemfile, I also uncommented the bcrypt gem and ran a bundle install so that I could use it. I also created and migrated my database so that I can begin saving users to it. Finally, I added this validation to my user model as it allows passwords to be encrypted through bcrypt:

class User < ApplicationRecord
has_secure_password
end

If you do not have a program such as Postman installed now is the time to do so, as it will allow you to test your backend’s endpoints without worrying about a front end at the moment.

Step II: Create a Test User

Once you have completed the setup it is time to create the first user and test the authentication method. This will ensure that we are able to retrieve an instance of our user back when we call the authenticate method on a user passing the correct password. To do so we are going to enter the rails console via the terminal:

$ rails c
//once the console starts run:
$User.create(username:”admin”, password: “testpassword”)

We should see this when we return if we successfully created our user:

Feel free to give your user whatever username and password you choose.
//Next we to test our user save them to a variable
$ admin = User.first

Now that we have our user saved to a variable we can test them using the authenticate method provided to us by the bcrypt gem, which will compare username and password digest with those in the database and return true or false:

Here we are passing in the wrong password
Here we are getting back the instance of our user. Notice that the password digest has come back to us [FILTERED], bcrypt is working under the hood to hide this information for us so that other people cannot see what the password digest is.

Step III: Set up the Auth Controller and Login Route

Now that we know we can get a user back it is time for us to begin building out our login method and routes. I have been exposed to several different places as to where this method should live in your program. While it can be housed under the Users Controller, it can also be under a custom controller. Personally, I prefer to create a new Auth Controller to handle this to keep these responsibilities separate (if you are new to auth continue following along, but feel free to do whatever makes the most sense once you feel more comfortable with this process). In the terminal we will run the command:

$ rails g controller Auth

Once we have created our controller it is also important to set up a custom route to serve as our login endpoint. Go into the routes file we will create a “POST” route for login:

Rails.application.routes.draw do
post '/login', to: 'auth#login'
end
// We are using a ‘POST’ request because it will send our information to our database in a more secure method than a ‘GET’ request.

After we have created our route we can now define the login method in our auth controller:

class AuthController < ApplicationController
def login
end
end

For now we won’t add anything to the method and will handle that in the next step while testing with postman.

Step IV: Filling out the Login Method

Now that we have defined our method it is time to figure out what will go into it. To do this we are first going to test that our login endpoint is working. First in our console we are going to start our localhost server:

$ rails s

First we are going to make sure our request method is set to “POST”. Second, we are going to change our url to “localhost:3000/login”. Next we are going to change the tab under the method and address from params to body. Once the tab changes over select raw and change the TEXT option to JSON. FInally in the body itself we will be adding an object of two things: the username and password. Once you are done your Postman window should resemble this:

All that is left is to hit send. If you have done everything correctly you should not see any error messages(you wont get a response back just yet). The reason we are testing like this without actually adding anything in our method is to make sure that we have our action and our route. If either are missing we will be given a 404 error in our results tab.

After we see that our method is connected we will pass a byebug in to our login method. This will allow us to see what we are passing as params:

class AuthController < ApplicationController
def login
byebug
end
end

After saving this hit send once more in Postman to enter the bye bug. Once we are in the bye bug we can find out what the parameters are simply enter params into the console and return it:

Our params will show us what we sent when we made our post request. There are three important parts to focus on here. First our username, second the password, and finally at the end ‘permitted: false.’ Right now we are only going to focus on the username, and password and come back to the ‘permitted: false’ while creating the signup method in a future article. From here we should try our authentication method again. We will do this throuh the console, by saving the user to a variable running the authenticate method on that user with the password that was passed in, albeit it will look a bit different this time around because we are going to use our params to do it.

$ admin = User.find_by(username: params[:username])
$admin.authenticate(params[:password])
// If the correct password was passed in via postman it will return the user otherwise we will get false back.

Now that we can find and authenticate our user with paramswe can begin to fill out our Auth Controller’s login method. First we want to find a user and authenticate them. After that we want to get some kind of response back, if it is a successful attempt, we should get back the JSON of the user if not then we should render some errors:

class AuthController < ApplicationController
def login
user = User.find_by(username: params[:username])
is_authenticated = user.authenticate(params[:password])
if is_authenticated
render json: user
else
render json: {error: “Wrong username/password. Please try again!”}
end
end
end
Line by line breakdown:
// First we find our user
// Then we attempting to authenticate them
// If we get a truthy response we will render the json of the user
// Else we will render an error message.

With this we have handled the basics of logging in. If we pass the username with the correct password we can get the correct user back; if not we get an error:

Here we passed the correct password and got the user back
Here we passed the incorrect password and got our error back

With this we have successfully set up the basics of logging in a user to our web applications!

Final Code Snippets

//Routes
Rails.application.routes.draw do
post '/login', to: 'auth#login'
end
//Auth Controller
class AuthController < ApplicationController
def login
user = User.find_by(username: params[:username])
is_authenticated = user.authenticate(params[:password])
if is_authenticated
render json: user
else
render json: {error: “Wrong username/password. Please try again!”}
end
end
end
// Users Model
class User < ApplicationRecord
has_secure_password
end

Conclusion

Phew, that was a lot! In this blog post we have covered how to create a basic login and how you can test it out along the way. In the next part of this series I will begoing over how to handle the singup of a new user and some important validations for the user model. Stay tuned for next part of the series! Happy coding!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store