Login and Authenticate in Rails

Sam Jomaiv
4 min readSep 16, 2021

Have you ever wondered what happens under the hood of a website when you log in to your account? Well in this lesson I will explain that in detail:

🔑 How a log-in page is created

🔑 How it authenticates and logs in users

🔑 How to log-out of a session

In order to create a Login Page, we will use React.js (Fron-End) and Ruby on Rails(back-end)

When we create a rails app, we need to create our models using the “rails generator” command:

rails g resource model_name column_name:integer column_name:string

(you need to run this command for each model)

It generates the following:

•Routes

•Models

•Controllers

•Serializers for our Models

•Migrations(you need to seed some data)

These are the main things we need to create a Rails app and Now let’s write some code inside our Controllers which is where we write our logic.

Authenticate

What is authentication?

User authentication is a process in which you verify that someone who is attempting to access services and applications is who they claim to be. This can be accomplished through a variety of authentication methods, such as entering a password into your laptop or phone or a PIN number into the ATM.

We are going to create a “Sessions” controller (which is not created with “ralis g resource” command) and the command for that is:

rails generate scaffold_controller Sessions

It will generate all the necessary components including the route.

post "/login", to: "sessions#create"

As you can see we routed the login page to: sessions#create (session controller and create action)

Here is the Sessions Controller with #create action written inside of it:

class SessionsController < ApplicationController
def create
user = User.find_by(username: params[:username])
session[:user_id] = user.id
render json: user
end
end

Let me break it down for you…

In the “create action” of the SessionsController we set a cookie on the user's browser by writing their user ID into the session hash.

user = User.find_by(username: params[:username])

Inside our create action method (def create) Rails is looking for the user to see if it exists in the database which is where our username and password are saved and stored securely.

session[:user_id] = user.id

If the user exists, it will log in, a cookie on the user’s browser will be set by writing their user ID into the session. Thereafter session[:user_id] will hold their user ID. This is how we get authenticated!

Now our backend and Front-end know who we are(assuming you have a front end) but what happens when we refresh the page? unfortunately, we get logged out of our session. Here is how to make sure we stay logged in: we need a route to retrieve the user’s data from the database using the session hash:

get "/me", to: "users#show"

Now we need to create a new Controller, “UsersController”.

class UsersController < ApplicationController
def show
user = User.find_by(id: session[:user_id])
if user
render json: user
else
render json: { error: "Not authorized" }, status: :unauthorized
end
end
end

In “UsersController”, as you can see, we have a #show action which will be used to keep us signed in. Here is some example of how your Front_End might look like:

function App() {
const [user, setUser] = useState(null);
useEffect(() => {
fetch("/me").then((response) => {
if (response.ok) {
response.json().then((user) => setUser(user));
}
});
}, []);
if (user) {
return <h2>Welcome, {user.username}!</h2>;
} else {
return <Login onLogin={setUser} />;
}
}

We are fetching from ("/me")and saying if the response is ok, set our current state to “user” (which is a “useState()” hook)

if (user) {
return <h2>Welcome, {user.username}!</h2>;
} else {
return <Login onLogin={setUser} />;
}
}

Then we use conditional statements to render our user to the Front-End. Basically, the code above is saying if user is true (meaning it exists in our database) then show us Welcome text along with the user’s username. Otherwise, if the user is not in our database, send the user to the Login page.

What if want to log out? This is one is easy! We can simply delete the session hash which will log us out. Here is how we do it:

delete "/logout", to: "sessions#destroy"

Create a route for Logout in the SessionController with #destroy action.

class SessionsController < ApplicationControllerdef destroy
session.delete :user_id
head :no_content
end

What “destroy” method does is, that it will delete the stored user_id in the session hash which will result in the user being logged out of the page.

Conclusion

That’s it, you know how a log-in and log-out feature works in Rails using REST API. To recap login is very simple: the user provides you with credentials in the login form, the database verifies if a given user’s credentials exist in the database(back-end) and our front end will log us in with an appropriate message and data from the database. In order to stay logged in in the front-end, we create a session hash that will store our user_id. If we wanted to log out of that session we can simply delete that hash and we are out.

--

--