Rails authentication from scratch

If you're like me, you probably take Devise for granted because you're too intimidated to start your own authentication system. As powerful as Devise is, it's not perfect. There are plenty of instances where I've reached it only to end up being limited by its functionality and design, and I wish I could customize it exactly to my liking.

Fortunately, Rails gives you all the tools you need to run your own authentication system from scratch without needing to depend on a gem. The challenge is simply how to account for edge cases while being aware of security and best practices.

Previous releases

This guide is continually updated to reflect best practices. You can view previous versions here.

Step 1: Create a user model Generate a user model. g model rails User Email: string # db/migrate/[timestamp]_create_users.rb class CreateUsers < ActiveRecord::Migration[6.1] definitely change create_table: users do |t| t.string:email, null:false t.timestamps finish add_index:users, :email, unique: true finish finish Run migrations. rails db:migrate Add validations and callbacks. #app/models/user.rb class User < ApplicationRecord before_save: downcase_email valid:email, format: {with: URI::MailTo::EMAIL_REGEXP}, presence: true, uniqueness: true private def downcase_email self.email = email.downcase finish finish

What's going on here?

We prevent empty values ​​from being saved in the email column via a null: false constraint in addition to presence validation. We enforce unique email addresses at the database level via add_index :users, :email, unique: true in addition to uniqueness validation. We ensure that all emails are valid through format validation. We save all emails to the database in a tiny format via a before_save callback so that the values ​​are saved in a consistent format. We use URI::MailTo::EMAIL_REGEXP that comes with Ruby to validate that the email address is formatted correctly. Step 2: Add confirmation and password columns to the users table Create a migration. rails g migration add_confirmation_and_password_columns_to_users confirm_at:datetime password_digest:string Update migration. # db/migrate/[timestamp]_add_confirmation_and_password_columns_to_users.rb class AddConfirmationAndPasswordColumnsToUsers < ActiveRecord::Migration[6.1] definitely change add_column :users, :confirmed_at, :datetime add_column:users, :password_digest, :string, null:false finish finish

What's going on here?

The

Rails authentication from scratch

If you're like me, you probably take Devise for granted because you're too intimidated to start your own authentication system. As powerful as Devise is, it's not perfect. There are plenty of instances where I've reached it only to end up being limited by its functionality and design, and I wish I could customize it exactly to my liking.

Fortunately, Rails gives you all the tools you need to run your own authentication system from scratch without needing to depend on a gem. The challenge is simply how to account for edge cases while being aware of security and best practices.

Previous releases

This guide is continually updated to reflect best practices. You can view previous versions here.

Step 1: Create a user model Generate a user model. g model rails User Email: string # db/migrate/[timestamp]_create_users.rb class CreateUsers < ActiveRecord::Migration[6.1] definitely change create_table: users do |t| t.string:email, null:false t.timestamps finish add_index:users, :email, unique: true finish finish Run migrations. rails db:migrate Add validations and callbacks. #app/models/user.rb class User < ApplicationRecord before_save: downcase_email valid:email, format: {with: URI::MailTo::EMAIL_REGEXP}, presence: true, uniqueness: true private def downcase_email self.email = email.downcase finish finish

What's going on here?

We prevent empty values ​​from being saved in the email column via a null: false constraint in addition to presence validation. We enforce unique email addresses at the database level via add_index :users, :email, unique: true in addition to uniqueness validation. We ensure that all emails are valid through format validation. We save all emails to the database in a tiny format via a before_save callback so that the values ​​are saved in a consistent format. We use URI::MailTo::EMAIL_REGEXP that comes with Ruby to validate that the email address is formatted correctly. Step 2: Add confirmation and password columns to the users table Create a migration. rails g migration add_confirmation_and_password_columns_to_users confirm_at:datetime password_digest:string Update migration. # db/migrate/[timestamp]_add_confirmation_and_password_columns_to_users.rb class AddConfirmationAndPasswordColumnsToUsers < ActiveRecord::Migration[6.1] definitely change add_column :users, :confirmed_at, :datetime add_column:users, :password_digest, :string, null:false finish finish

What's going on here?

The

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow