Your Auth Cheat Sheet
Sean Oh
Posted on September 13, 2022
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)
Cookies and Sessions
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.
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."
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.
Authentication & Authorization
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
References
Posted on September 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.