DEV Community

Cover image for Authentication Without Complexity: Rails' Built-in Solution
Chandra Shettigar
Chandra Shettigar

Posted on

Authentication Without Complexity: Rails' Built-in Solution

In an industry where adding a simple login system often means wrestling with gem dependencies and configuration files, Rails has taken a refreshingly contrarian stance: what if authentication could be both secure and simple?

The typical authentication story in web development reads like a cautionary tale: start with a third-party gem, sprinkle in some middleware, juggle configuration files, and pray nothing breaks during the next framework update. It's a complexity tax we've been paying for so long that we've forgotten to question it.

Rails 8 suggests a different path. Let's explore how a single generator command challenges years of authentication complexity.

1. Generate Authentication System

# Generate the authentication system
rails generate authentication
Enter fullscreen mode Exit fullscreen mode

This generates a focused set of files - notably fewer than traditional authentication gems, but that's by design:

# Generated migrations
db/migrate/YYYYMMDDHHMMSS_create_users.rb
db/migrate/YYYYMMDDHHMMSS_create_sessions.rb

# Generated models
app/models/user.rb
app/models/session.rb
app/models/current.rb

# Generated controllers
app/controllers/sessions_controller.rb    # Handles sign in/out
app/controllers/passwords_controller.rb   # Handles password reset

# Generated views
app/views/passwords/new.html.erb         # Password reset request
app/views/passwords/edit.html.erb        # Password reset form

# Generated mailers
app/mailers/passwords_mailer.rb
app/views/passwords_mailer/reset.html.erb
app/views/passwords_mailer/reset.text.erb
Enter fullscreen mode Exit fullscreen mode

2. Set Up Landing Page

# Generate home controller for public landing 
rails generate controller Home index
Enter fullscreen mode Exit fullscreen mode
# config/routes.rb
Rails.application.routes.draw do

  # Authentication routes added
  resource :session
  resources :passwords, param: :token
  # - new_session_path (GET) -> Sign in form
  # - session_path (POST) -> Create session (sign in)
  # - session_path (DELETE) -> Sign out
  # - new_password_path (GET) -> Password reset request
  # - edit_password_path (GET) -> Password reset form
  # - password_path (PATCH) -> Update password

  root "home#index"

  # Some user dashboard 
  resources :dashboard
end
Enter fullscreen mode Exit fullscreen mode

3. Run Migrations

rails db:migrate
Enter fullscreen mode Exit fullscreen mode

This sets up:

  • Users table with secure password handling
  • Sessions table for managing sign-ins

4. Add User Registration

Rails intentionally leave registration open-ended - because no two applications handle user signup the same way and it makes sense not to include it in the auth generator. Here's a minimal implementation:

# app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
  allow_unauthenticated_access

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      # Optionally sign in the user after registration
      start_new_session_for @user
      redirect_to root_path, notice: "Welcome!"
    else
      render :new, status: :unprocessable_entity
    end
  end

  private

  def user_params
    params.require(:user).permit(:email, :password, :password_confirmation)
  end
end
Enter fullscreen mode Exit fullscreen mode

Add the routes:

# config/routes.rb
Rails.application.routes.draw do
  resources :registrations, only: [:new, :create]
  # ... other routes
end
Enter fullscreen mode Exit fullscreen mode

5. Protect Your Controllers

# app/controllers/dashboard_controller.rb
class DashboardController < ApplicationController
  before_action :require_authentication

  def index
    @projects = Current.user.projects
  end
end

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  allow_unauthenticated_access only: [:index]

  def index
    # Your public landing page
  end
end
Enter fullscreen mode Exit fullscreen mode

Key Features You Get For Free

  • Secure password hashing with bcrypt
  • Session management with secure tokens
  • Automatic session resumption across browser restarts
  • Password reset via email
  • CSRF protection
  • Secure post-authentication redirects
  • XSS protection headers

A Note on Design Philosophy

Rails' authentication system exemplifies a crucial architectural principle: sophistication through simplicity. Instead of the kitchen-sink approach, you get:

  • Core authentication logic that's secure
  • Freedom to implement registration and user management your way
  • No framework lock-in for additional features
  • Clear separation between authentication and user functionality

This approach acknowledges a truth many frameworks miss: while authentication fundamentals are universal, user management rarely is.

Further Reading

For those interested in diving deeper:

  1. Rails Authentication from Scratch - If you don't want to use any gems like devise and if you were to create all the views, controllers, models, and mailers to build a simple authentication
  2. Rails 8 Authentication Deep Dive - Great article to learn a bit more about the rails authentication generator
  3. Ruby on Rails Guide - Official documentation

Building Your Own

While Rails now provides authentication out of the box, understanding how to build it from scratch remains valuable. The GoRails tutorial walks through implementing similar functionality manually - a great exercise for understanding the security principles at play.

Remember: the best authentication system isn't the one with the most features, but the one that provides security without sacrificing developer productivity or application flexibility.

Top comments (0)