Authenticating Users in Rails
Tags: rails, beginners, tutorial
Published: 2023-01-14 03:27:36


![unauthorized](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpualqosrnsm9iirnjx4.png)

Logging in.

All websites do it, and as internet users, we don't think about logging in or logging out or weird things like creating a "user session." 😵‍💫

But all of that goes on in the backend in Rails. 


Think of websites like the club; they use a "stamp." You arrive, and the bouncer checks your id and gives you a stamp. If you leave and come back later (...maybe after visiting that White Castle), the bouncer doesn't recheck your id; they just check for your stamp. You can get a drink at the bar because your stamp proves you're old enough and have already been checked in.


## Website example of the stamp pattern ✋🏽:


You log in at etsy.com. Etsy's servers authenticate you.

If your credentials are correct, Etsy's servers issue a cookie to your browser.

If you visit another protected page on Etsy, your browser will show the cookie to the server; the server verifies the cookie and lets you load password-protected info and browse in a logged-in state.

As developers, we describe this process as authentication. When we talk about authentication in our applications, we're describing how an application can confirm that a user is who they say they are. 

##How to authenticate users in Rails:

For a Flatiron boot camp project, I created a rails app called dogGo! which allows you to view and review dog walkers. 


![doggo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tl4x9i5apaqbc7yimhqg.png)



At the core of this app is authentication. We don't want someone walking in the front door of this app without signing up and logging in. So this is how I built that functionality:

1. The user navigates to my homepage, which in my case is React.
2. The user enters their username and password.
3. **POST**ing to /login  or /signup on the Rails backend
4. If the user is signing up, then we are going to **CREATE** a new user with a secure password. If the user is logging in (checking their stamp) then we are going to **CREATE** a new session with a cookie:

**Sign up**:


![signup back](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/splu59g3hu72kzc8j234.png)

![Sign up front](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cgntortb9cve5uegxy5e.png)


**Login**:


![Login Back](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ga11z8ms2cty6hmex5j5.png)

![Login front](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rtb76cu0ftovvl78kdfo.png)



**IMPORTANT**: Typically, your create login method will look up a user in the database, verify their login credentials, and then store the authenticated user's id in the session.

What the component might look like on the frontend

![Login on the front](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ci54hdpya55rp6xs4s60.png)


When the user submits the form, they'll be logged in! Our callback function would handle saving the logged in user's details in state.

## Staying Logged In

We've shown our ID at the door (username) and gotten our stamp (session[:user_id]) from the backend. So our backend has a mean of identifying us with each request using the session hash.

Our frontend knows who we are, because our user data was saved in state after logging in.

BUT - what happens if we refresh the page in the browser? Well, the frontend doesn't know who we are anymore since we lose frontend state on page refresh, but the backend know who we are - so we need a way of getting the user data from the backend into state when the page firsts loads. 

First, we need a custom route to retrieve the user's data from the database using the session hash:


![Custom route](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htfqr37jsfd95csovb71.png)



**And a controller action:**


![custom controller route](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/061amm6nuhgwlazwsek1.png)


Then we can try to log the user in from the frontend as soon as the application loads, else return a login screen:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwhp1doewlqbipdzt0m7.png)


## Logging Out

It's simple to make a log out flow:

1. Add a new custom route for logging out:
2. Add a new action in the session controller, which will clear the username out of the session

![Log out](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72ryk9lbg9qxcd6ef8pw.png)

Add the code on the frontend. A button in the navbar perhaps:


![Log out again](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0amgdvbv6otj2o652krt.png)


In this example, setUser callback function would handle removing the information about the user from state.

Ok, lets all go enjoy those White Castle burgers while we wait in line to get back into the club 🍔