DEV Community

Gus Bikos
Gus Bikos

Posted on

A simple auth guide for Ruby on Rails

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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 %>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Top comments (0)