Your Auth Cheat Sheet
Tags: authentication, authorization, rails, cheatsheet
Published: 2022-09-13 02:28:57

I'm not gonna lie; it took me quite some time to understand (and I'm still taking steps to get closer to the full understanding of it) the fundamental concepts of sessions, cookies, authentication and authorization along with password protection (including the crazy processes with BCrypt) in Rails.  In this post, I'm just going to dabble in each concept mentioned above to give you an idea, then share my "cheat sheet" that will hopefully help you with writing sign-up and log-in/out features on your Rails backend.  As the frontend design for these features is all about creativity, I will leave it up to you on that part. ~~(of course not because I'm too lazy to come up with an example)~~

---

## <u>Cookies and Sessions</u>

Even not as a developer, you might have heard of _cookies_ before.  And there is another thing called _sessions_ when you dive deeper into learning the auth concept in Rails.  So what are exactly _cookies_ and _sessions_?  Let's say that you recently bought a new laptop, and you're so excited to use it.  You'd browse on the internet, send emails, shop online, etc.  In order for you to do these things, you have probably accessed google.com, gmail.com, amazon.com, etc.  In the websites' perspectives, since you have just unboxed your new laptop and accessed those websites "for the first time," these websites would have no idea who you are.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hrc87bd7p5en6tg1at7.gif)

Seeing you for the first time ever, the website's reaction would probably be like "Hey, I've never seen you before.  It's nice to meet you.  So that I can recognize you, please have this _name tag_ with you next time you visit here."

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

In this analogy, you can think of the _name tag_ as _**cookies**_.  It is a unique distinguisher for your (new) laptop so that the website doesn't have to ask who you are (or what other information you have with you) every time you visit there.  Now that your laptop (or your browser) has _cookies_, the website will have to remember the fact that it has assigned you those _cookies_.  To do so, the website's server will make a list of the name tags(_cookies_) it has assigned to various computers and browsers.  Now this "list" is called a **_session_**.  Going forward, when you visit the website (which you've previously visited) with the name tag(_cookie_) you've been assigned with, the website will see if your name tag(_cookie_) is in the list(_session_) of the name tags that it has assigned before to determine whether or not you have already visited this website in the past.

---

## <u>Authentication & Authorization</u>

Authentication and authorization are two vital information security processes that administrators use to protect systems and information.  They may seem to be conceptually the same, but have slightly different aspects in what they imply.

**Authentication** verifies the identity of a user or service.  That is, when you log into your Gmail account (if you have one) using your username and password, Google's server will issue your browser the above-mentioned cookie.  Then, as you navigate through several different pages on Gmail (or anywhere on google.com for that matter), your browser will show the cookie to the server, which the server then will verify the cookie and let you stay logged in.

**Authorization** determines the user's access rights.  In addition to authentication, authorization gives certain users permission to access specific resources.  For example, everyone can go to Apple Music to listen to whatever song they like for 90 seconds as "preview."  However, only the _authenticated_ users (those who paid for the premium service and logged into Apple Music) will be able to listen to the full songs, create their own playlists, etc.

---

Now it's time for what you've been waiting for... the cheat sheet!  I highly recommend, though, that you first have gained solid understanding of the auth process in Rails and fully understand what is going on under the hood before just referring to this cheat sheet because otherwise this cheat sheet would be a mere template that probably will not make any sense.

_/config/routes.rb_
```
Rails.application.routes.draw do
  post '/signup', to: "users#create"
  get '/me', to: "users#show"
  post '/login', to: "sessions#create"
  delete '/logout', to: "sessions#destroy"
end
```

_/app/models/user.rb_
```
class User < ApplicationRecord
    has_secure_password
end
```

_/app/controllers/users_controller.rb_
```
class UsersController < ApplicationController

    before_action :authorize, only: [:show]

    def create
        # create a new user
        # save their hashed password in the database
        user = User.create(user_params)
        # save the user's ID in the session hash
        if user.valid?
            session[:user_id] = user.id
        # return the user object in the JSON response
            render json: user, status: :created
        else
            render json: { error: user.errors.full_messages }, status: :unprocessable_entity
        end
    end

    def show
        # if the user is authenticated, return the user object in the JSON response
        user = User.find_by(id: session[:user_id])
        render json: user
    end

    private

    def user_params
        params.permit(:username, :password, :password_confirmation)
    end

    def authorize
        return render json: { error: "Not authorized" }, status: :unauthorized unless session.include? :user_id
    end

end
```

_/app/controllers/sessions_controller.rb_
```
class SessionsController < ApplicationController
  
  def create
    user = User.find_by(username: params[:username])
    if user&.authenticate(params[:password])
      session[:user_id] = user.id
      render json: user, status: :created
    else
      render json: { error: "Invalid username or password" }, status: :unauthorized
    end
  end

  def destroy
    session.delete :user_id
    head :no_content
  end

end
```

---

## <u>References</u>

- https://guides.rubyonrails.org/action_controller_overview.html#session

- https://guides.rubyonrails.org/action_controller_overview.html#cookies

- https://www.onelogin.com/learn/authentication-vs-authorization#:~:text=Authentication%20and%20authorization%20are%20two,authorization%20determines%20their%20access%20rights.

- https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password