DEV Community

Cover image for Rails 8: Introducing the Built-in Authentication Generator
JetThoughts Dev for JetThoughts

Posted on • Edited on • Originally published at jetthoughts.com

Rails 8: Introducing the Built-in Authentication Generator

Ruby on Rails developers face a common task: building user login systems. Rails 8 brings a built-in solution. This guide helps Rails developers create authentication without extra gems.

What Ruby Developers Will Build

As a Rails developer, you'll create:

  • A secure authentication system
  • Public and private pages
  • A test suite for user flows
  • Database migrations for users

Set Up Your Rails Environment

Ruby on Rails developers start here:

rails new auth-example
cd auth-example
Enter fullscreen mode Exit fullscreen mode

This creates a fresh Rails application.

Rails 8 Authentication Generator

Rails developers love simple solutions. Run:

bin/rails generate authentication
Enter fullscreen mode Exit fullscreen mode

The generator creates Rails files:

  • ERB view templates
  • Rails controllers
  • Ruby models
  • RSpec test files

Database Setup for Rails

Rails developers need a working database:

bin/rails db:create db:migrate
Enter fullscreen mode Exit fullscreen mode

Create a test user in Rails console:

rails c
Enter fullscreen mode Exit fullscreen mode

Add user data:

User.create(email_address: "you@example.com", password: "test-password-123")
Enter fullscreen mode Exit fullscreen mode

Rails Controllers

Rails developers work with two types of access:

  • Public pages for visitors
  • Private pages for users

Generate Rails controllers:

rails g controller home index
rails g controller dashboard show
Enter fullscreen mode Exit fullscreen mode

Ruby on Rails Routes

Rails routing connects URLs to Ruby code. Update config/routes.rb:

Rails.application.routes.draw do
  get "home/index", as: :home
  get "dashboard/show", as: :dashboard
  root "home#index"
end
Enter fullscreen mode Exit fullscreen mode

Public Controller in Rails

Ruby developers handle public access:

class HomeController < ApplicationController
  allow_unauthenticated_access(only: :index)
  def index
  end
end
Enter fullscreen mode Exit fullscreen mode

Authenticated Controller

Rails developers protect private pages:

class DashboardController < ApplicationController
  before_action :resume_session, only: [:show]
  def show
  end
end
Enter fullscreen mode Exit fullscreen mode

Test Your Rails App

Start your Rails server:

rails s
Enter fullscreen mode Exit fullscreen mode

Test these Rails routes:

  1. /home - Public access
  2. /dashboard - Login required

Rails Security Tips

Ruby developers follow these practices:

  • Use secure passwords
  • Keep Rails updated
  • Monitor logs
  • Back up data

Rails Authentication Code

View the Ruby code: Rails Authentication Source

Tasks for Rails Developers

Try these Ruby tasks:

  1. Build a signup flow
  2. Create a password reset
  3. Add session persistence
  4. Style your ERB templates

Next Steps for Rails Developers

You can extend this:

  • Add OAuth support
  • Create admin roles
  • Add API authentication
  • Build user profiles

Remember: Now, the Rails developer starts with basic authentication. Build more. Learn more.

Need Ruby on Rails help? Drop questions below.

Top comments (2)

Collapse
 
salex profile image
Steve Alex

Of the few posts I could find on Rails 8 new athentication, this was one of the best. At least it defined the difference between Home and Dashboard.

I've been thinking about rewritting a new version of a app I started about 10 years ago. It's basically an Accounting app (Clients, Users, Books, Accounts, Entries, Split, etc.). I wrote it the keep the books for a VFW post, with possible use by other VFW posts. It uses acts_as_tennat to control client access.

Basic structure

  • class Client < ApplicationRecord has_many :users, dependent: :destroy has_many :books, dependent: :destroy
  • class User < ApplicationRecord acts_as_tenant(:client) ### for acts_as-tenant
  • class Book < ApplicationRecord acts_as_tenant(:client) ### for acts_as-tenant has_many :accounts, dependent: :destroy
  • class Account < ApplicationRecord belongs_to :book

I got the basic authentication working even with User belonging to Client.

Were I'm stuck is where do I put and manage other session stuff?

I have Current.book that is set when I open a book of accounts. Once set, how do I persist it?

I tried a kludge by adding a JSON hash 'setting' in Session. I could puts stuff in it like [:book_id] that I could use to set Current.book. But where to I manage setting Current.book if its in session.settings.

Figured I'd ask for ideas. Again, good post.

Collapse
 
salex profile image
Steve Alex

I though I'd give an approach to answering my question.

The base models Session, User are just rails model. You can add stuff to them if needed. My User model had roles, client_id and a few other things that I added at the start. Adding thesetting hash doesn't affect authentication, but solves my Current.book problem.

My application controller:

class ApplicationController < ActionController::Base
  include Authentication

  set_current_tenant_through_filter  ### for acts_as-tenant
  before_action :current_sessions
  # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
  allow_browser versions: :modern

  def current_sessions
    if Current.session.present?
      if Current.session.settings.blank?
        # puts "session.settings blank" no book, exit
      else
        # puts "Got setings #{Current.session.settings}"
        if Current.session.settings["book_id"].present?
          # "Got curr book #{Current.session.settings}"
          Current.book = Book.find(Current.session.settings["book_id"])
        end
        # maybe others
      end
    end
  end
  ...
Enter fullscreen mode Exit fullscreen mode

It just does the current model get with some filtering when it does it.

My Books controller has an open method that puts stuff in the session model that the current_sessions method responds to.

  def open
    Current.session.settings = {} if Current.session.settings.blank?
    Current.session.settings["book_id"] = @book.id
    Current.session.save
    Current.book = @book
    redirect_to book_path(@book), notice: "Current Book set"
  end
Enter fullscreen mode Exit fullscreen mode

It does a save on the session model and works just fine.