Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 5, 2022 09:59 pm GMT

Authorization and Authentication in Ruby on Rails

Overview

Authorization and authentication are two valuable areas of coding to understand. In this summary, I will be going over what authentication and authorization are and how to make a simple login form, including a username input that will be used to determine who the user is and whether they are authorized to view a post.

By the way, when I use the word "auth" I am referring to both authorization and authentication as a whole, not one or the other and not something else entirely.

Authentication versus authorization

Authorization refers to what a user has access to; authentication refers to the verification of who a user is. Both of these are important for user security because validation of a user can prevent unwanted actions, such as admin access, from affecting the program/user in a negative way.

Cookies

Cookies are data that are stored in a browser while a website is being used by a client. Cookies are generally client-side, not server-side. Their purpose is to remember information about the user, and they can be created as plain-text name-value pairs, such as user_name=eric.

cookies[:user_name] = "eric"

Cookies can also be set as hashes and have attributes, such as expiration dates/times.

cookies[:login] = { :value => "Eric", :expires => Time.now + 1.hour}

This cookie, stored as the symbol :login, has a value set as "Eric" and it expires and is deleted 1 hour from the current time.

One issue with cookies is that since they are generally plain-text, their information can be accessed by anyone, causing security concerns. Below is a special type of cookie, called a session, that helps resolve this security issue.

Sessions

Sessions are data that are stored on the server side. They are a specialized cookie that adds a signature to the cookie, encrypting it and preventing clients from tampering with its data. The following is a way to set up a session:

session[:user_id] = user.id// stores the user's ID into an encrypted session ID that is several characters long

In the code above, the session method will create a signature specifically for the value of the [:user_id] key and assign the value of the user's ID to that signed value. This way, it is difficult for a malicious user to access the user_id.

Code for allowing your program to use sessions and cookies

Here is some starter code for allowing cookies and sessions to be used in your program:

class Application < Rails::Application   config.middleware.use ActionDispatch::Cookies   // allows one to use cookies in their program   config.middleware.use ActionDispatch::Session:CookieStore   // allows one to use sessions in their program   config.action_dispatch.cookies_same_site_protection =    :strict   // makes sure that cookies are only accepted    within applications on the same domain as the    program, rather than different domains, for    security of our programend
class ApplicationController < ActionController::API   include ActionController::Cookiesend// This allows our application controller, which other controllers would generally inherit from, to use cookies

Creating a login form with a username

Authentication could be done in Ruby with a create action using POST:

post "/login" to sessions#create

In the above code, post refers to the POST restful action that allows one to persist a new instance of a login to the database; sessions refers to the controller that will be performing the create action via a create method.

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

Below is how React could save the username in state. After making a POST request via a submit button on a React form, the default empty string of username (from useState("") is replaced with the username retrieved from the Ruby backend. The username is converted into a JavaScript object in the body of the request and then passed into the login callback function as a parameter called user.

function Login({ handleLogin }) {  const [username, setUsername] = useState("");  function handleSubmit(e) {    e.preventDefault();    fetch("/login", {      method: "POST",      headers: {        "Content-Type": "application/json",      },      body: JSON.stringify({ username }),    })      .then((r) => r.json())      .then((user) => handleLogin(user));  }  return (    <form onSubmit={handleSubmit}>      <input        type="text"        value={username}        onChange={(e) => setUsername(e.target.value)}      />      <button type="submit">Login</button>    </form>  );}

Adding authorization to the login

The code above shows how one could take a user, save the user.id into the session[:user_id] and save the username in state, which shows on both the front end and back end that the user is authenticated. At the moment, all that is needed is the username, not the password.

To take this a step further, an authorize method could be added that allows certain actions by the user to be restricted unless they have logged in with a username. Below is code that could be used to do this for a program that renders posts:

class PostsController < ApplicationController   before_action :authorize   def show      post = Post.find_by(id:params[:id])      render json: post   end   private   def authorize      return render json: { error: "Unauthorized" }, status:       :unauthorized unless session.include? :user_id   endend

This code prevents a user without a user_id stored in the session to access the post. Basically, before the show method is run, the authorize method runs (before_action ensures that :authorize will run before any method within the PostsController), returning an error unless a user_id is stored in the session as a truthy value.

Summary

Here are some important takeaways from this blog:
1) Authentication and authorization are not the same.
2) POST is a useful RESTful action that can be applied to logging a user in.
3) Cookies are usually client-side, plain text, and not secure; sessions are server-side, signed cookies that are more secure than other unsigned cookies.
4) before_action allows one to use a method before any other methods within a class; the method, authorize, was the example used in this blog that determined whether or not a user could make a post.
5) Certain middleware needs to be set up in order to use cookies in a Rails application; :strict is an example of how to prevent different domains from making requests for cookies.

References

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

https://www.w3schools.com/js/js_cookies.asp

https://www.tutorialspoint.com/ruby-on-rails/rails-session-cookies.htm

https://www.youtube.com/watch?v=IzbQAj_tcfI

https://learning.flatironschool.com/


Original Link: https://dev.to/ericeinerson/authorization-and-authentication-in-ruby-on-rails-178k

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To