dchuk/rails_ai_agents · Archived

authentication-flow

Implements authentication using Rails 8 built-in generator. Use when setting up user authentication, login/logout, session management, password reset flows, or securing controllers.

First seen Feb 13, 2026

Installation

$ npx skills add dchuk/rails_ai_agents --skill authentication-flow

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from dchuk/rails_ai_agents · top by installs.

npx skills add dchuk/rails_ai_agents

Browse all from dchuk/rails_ai_agents

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

License LICENSE
Default branch main
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Write, Edit, Bash, Glob, Grep

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,447 B
  • docs SUMMARY.md 208 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

Rails 8 Authentication

Overview

Rails 8 includes a built-in authentication generator that creates a complete, secure authentication system without external gems.

Quick Start

# Generate authentication
bin/rails generate authentication

# Run migrations
bin/rails db:migrate

This creates:

  • User model with hassecurepassword
  • Session model for secure sessions
  • Current model for request-local storage
  • Authentication concern for controllers
  • Session and Password controllers
  • Login/logout views

Generated Structure

app/
├── models/
│   ├── user.rb              # User with has_secure_password
│   ├── session.rb           # Session tracking
│   └── current.rb           # Current.user accessor
├── controllers/
│   ├── sessions_controller.rb      # Login/logout
│   ├── passwords_controller.rb     # Password reset
│   └── concerns/
│       └── authentication.rb       # Auth helpers
└── views/
    ├── sessions/
    │   └── new.html.erb     # Login form
    └── passwords/
        ├── new.html.erb     # Forgot password
        └── edit.html.erb    # Reset password

Core Components

User Model

# app/models/user.rb
class User < ApplicationRecord
  has_secure_password
  has_many :sessions, dependent: :destroy

  normalizes :email_address, with: -> { _1.strip.downcase }

  validates :email_address, presence: true, uniqueness: true,
            format: { with: URI::MailTo::EMAIL_REGEXP }
end

Session Model

# app/models/session.rb
class Session < ApplicationRecord
  belongs_to :user

  before_create { self.token = SecureRandom.urlsafe_base64(32) }

  def self.find_by_token(token)
    find_by(token: token) if token.present?
  end
end

Current Model

# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :session
  delegate :user, to: :session, allow_nil: true
end

Authentication Concern

# app/controllers/concerns/authentication.rb
module Authentication
  extend ActiveSupport::Concern

  included do
    before_action :require_authentication
    helper_method :authenticated?
  end

  class_methods do
    def allow_unauthenticated_access(**options)
      skip_before_action :require_authentication, **options
    end
  end

  private

  def authenticated?
    Current.session.present?
  end

  def require_authentication
    resume_session || request_authentication
  end

  def resume_session
    if session_token = cookies.signed[:session_token]
      if session = Session.find_by_token(session_token)
        Current.session = session
      end
    end
  end

  def request_authentication
    redirect_to new_session_path
  end

  def start_new_session_for(user)
    session = user.sessions.create!
    cookies.signed.permanent[:session_token] = { value: session.token, httponly: true }
    Current.session = session
  end

  def terminate_session
    Current.session&.destroy
    cookies.delete(:session_token)
  end
end

Usage Patterns

Protecting Controllers

class ApplicationController < ActionController::Base
  include Authentication
  # All actions require authentication by default
end

class HomeController < ApplicationController
  allow_unauthenticated_access only: [:index, :about]
end

Accessing Current User

# In controllers and views
Current.user
Current.user.email_address

Login Flow

# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  allow_unauthenticated_access only: [:new, :create]

  def new
  end

  def create
    if user = User.authenticate_by(email_address: params[:email_address],
                                    password: params[:password])
      start_new_session_for(user)
      redirect_to root_path, notice: "Signed in successfully"
    else
      flash.now[:alert] = "Invalid email or password"
      render :new, status: :unprocessable_entity
    end
  end

  def destroy
    terminate_session
    redirect_to root_path, notice: "Signed out"
  end
end

Testing Authentication

Test Helper

# test/test_helper.rb
class ActionDispatch::IntegrationTest
  def sign_in(user)
    session = user.sessions.create!
    cookies[:session_token] = session.token
  end

  def sign_out
    cookies.delete(:session_token)
  end
end

Session Controller Tests

# test/controllers/sessions_controller_test.rb
require "test_helper"

class SessionsControllerTest < ActionDispatch::IntegrationTest
  setup do
    @user = users(:one)
  end

  test "GET new renders login form" do
    get new_session_path
    assert_response :success
  end

  test "POST create with valid credentials signs in user" do
    post session_path, params: {
      email_address: @user.email_address,
      password: "password123"
    }

    assert_redirected_to root_path
    assert cookies[:session_token].present?
  end

  test "POST create with invalid credentials shows error" do
    post session_path, params: {
      email_address: @user.email_address,
      password: "wrong"
    }

    assert_response :unprocessable_entity
  end

  test "DELETE destroy signs out user" do
    sign_in @user

    delete session_path

    assert_redirected_to root_path
    assert_nil cookies[:session_token]
  end
end

Protected Route Tests

# test/controllers/posts_controller_test.rb
require "test_helper"

class PostsControllerTest < ActionDispatch::IntegrationTest
  setup do
    @user = users(:one)
  end

  test "redirects to login when not authenticated" do
    get posts_path
    assert_redirected_to new_session_path
  end

  test "shows posts when authenticated" do
    sign_in @user

    get posts_path
    assert_response :success
  end
end

References

  • See [sessions.md](reference/sessions.md) for session management details
  • See [current.md](reference/current.md) for Current attributes patterns
  • See [passwordless.md](reference/passwordless.md) for magic link authentication

Common Customizations

Remember Me

def start_new_session_for(user, remember: false)
  session = user.sessions.create!
  cookie_options = { value: session.token, httponly: true }
  cookie_options[:expires] = 2.weeks.from_now if remember
  cookies.signed.permanent[:session_token] = cookie_options
  Current.session = session
end

Multiple Sessions Tracking

def active_sessions
  sessions.where("created_at > ?", 30.days.ago)
end

def terminate_all_sessions_except(current_session)
  sessions.where.not(id: current_session.id).destroy_all
end

Rate Limiting

# app/controllers/sessions_controller.rb
rate_limit to: 10, within: 3.minutes, only: :create,
           with: -> { redirect_to new_session_path, alert: "Too many attempts" }

Checklist

  • Authentication generator run
  • Test helper with signin/signout methods
  • Session controller tests written
  • Protected route tests written
  • Rate limiting on login
  • allowunauthenticatedaccess on public pages
  • All tests GREEN