A simple auth guide for Ruby on Rails
Gus Bikos
Posted on March 10, 2021
Building a website is awesome, you can design it anyway you want and present it to the world through the internet. An important thing to have on your website is as much security as possible, and for certain data not to slip into the hands of others. One way of setting up your website and reaching that goal is by using Auth.
Auth is a way to associate each new, or existing user that is stored in the database with only information that pertains to them. The way that happens is through cookies, and sessions.
Cookies are small pieces of text data that gets stored in your browser. Specific cookies known as HTTP cookies are used to identify specific users and improve your web browsing experience. Sessions has the same concept, but instead of saving data in plain text it saves the data in a long string of mashed up text that is hard for somebody to tamper with that users information.
A simple way to set up user auth would be as follows:
We can start off by generating a new rails Rails app.
rails new project
For the basic structure of user Auth we will have our User model.
Model
Our User model will only have two attributes, username and password.
rails g model user username password_digest
Controllers
The UsersController will have login, handle_login and logout actions that can be used in the routes.
-The login method does not necessarily need any logic for our simple app therefore we will leave it blank. But it will be associated with a form in our views login.erb file.
-The handle_login action just makes sure that if the user is signed in and is authenticated it will set a unique session to that user.
-The logout action just sets the session for that user_id to nil.
def login
end
def handle_login
@user = User.find_by(username: params[:username])
if @user && @user.authenticate(params[:password])
session[:user_id] = @user.id
redirect_to user_path(@user)
else
redirect_to login_path
end
end
def logout
session[:user_id] = nil
redirect_to login_path
end
The ApplicationController will have the actions current_user, logged_in?, and authorized.
-The current_user method returns the current user that is signed in and associated with there session.
-The logged_in? method return a boolean value on whether or not the user is signed in.
-The authorized method determines whether or not the user is authorized.
All the methods in your ApplicationController can be inherited from other Controllers using helper methods that are labeled on top of the ApplicationController. In addition to these helper methods Rails also has another before_action method which means the method followed by before_action will execute first in the Controller.
ApplicationController < ActionController::Base
helper_method :current_user, :logged_in?
before_action :authorized
def current_user
@current_user ||= User.find_by(id: session([:user_id)]
end
def logged_in?
!!current_user
end
def authorized
redirect to login_path unless logged_in?
end
Bcrypt
Bcrypt is a secure function that stores data in a form of a hash. It adds a built in read only attribute which is a boolean attribute. A read-only field can not be modified so nobody can tamper with your password. It also adds a validation field called password_confirmation which means when your signing up you have to enter your password twice to confirm it.
class User < ApplicationRecord
has_secure_password
end
Routes
Now we set up our routes under config/routes.rb.
Rails.application.routes.draw do
resources :users
get "/login", to: "users#login", as: "login"
post "/handle_login", to: 'users#handle_login'
delete "/logout", to: "users#logout"
View files
In your login.erb view file you will set up a form for your user to be able to login.
<%= form_tag "/handle_login" do %>
<%= label_tag :username, "Enter Username" %>
<%= text_field_tag :username %>
<%= label_tag :password, "Password" %>
<%= password_field_tag :password %>
<%= submit_tag "Login" %>
<% end %>
Creating a New User
When the user clicks on submit it will redirect you back to the UserController which will trigger a post request to the create action which looks like this:
def create
@user = User.create(params.require(:user).permit(:username,
:password))
session[:user_id] = @user.id
redirect_to '/login'
end
With the use of helper methods from the ApplicationController, we can also use the @current_user instance variable to do the same job as this create method and also add a unique session id to the new user instance.
This is great flexibility of utilizing helper methods. Assuming we have a private method called user_params we can use the method and pass it as an argument in our @current_user.
def create
@current_user.create(user_params)
redirect_to '/login'
end
Posted on March 10, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024