Authlogic

authentication-libraryRubyRailsActiveRecordsession-managementencryptionsecurity

Authentication Library

Authlogic

Overview

Authlogic is a simple and flexible authentication library for Ruby on Rails. Built on ActiveRecord with non-intrusive design that follows traditional MVC patterns. Unlike heavyweight solutions like Devise or Clearance, it provides minimal functionality while offering developers high levels of customization. As of 2025, it continues active development with the latest version 6.5.0 released.

Details

Authlogic is an ActiveRecord-based library for adding authentication functionality to Ruby on Rails applications. It features the following key characteristics:

  • ActiveRecord Integration: Add authentication features to User models with acts_as_authentic method
  • Session Management: Session models that inherit from Authlogic::Session::Base
  • Encryption: Password hashing with configurable crypto providers like BCrypt
  • Validation: Automatic validation for email addresses and password strength
  • Customizability: Flexible modification of authentication logic and validation rules
  • Non-intrusive Design: Does not alter existing model and controller structures

Pros and Cons

Pros

  • Simple and understandable design with low learning curve
  • Highly customizable allowing easy implementation of custom authentication logic
  • Intuitive API following ActiveRecord patterns
  • Lightweight with minimal impact on application performance
  • Stable development and maintenance over a long period
  • Easy integration into existing Rails applications

Cons

  • Modern authentication features (OAuth, 2FA, etc.) require manual implementation
  • Fewer standard features compared to Devise
  • More initial setup and configuration than other gems
  • Smaller community and ecosystem compared to Devise
  • Additional work required for integration with modern frontends (SPAs)
  • Limited built-in features for complex authentication scenarios

Reference Pages

Code Examples

Adding to Gemfile and Installation

# Gemfile
gem 'authlogic', '~> 6.5'

# Installation
bundle install

User Model Configuration

# app/models/user.rb
class User < ApplicationRecord
  acts_as_authentic do |config|
    config.email_field = :email
    config.require_password_confirmation = false
    config.validate_login_field = true
    config.validate_email_field = true
    config.validate_password_field = true
    config.merge_validates_length_of_email_field_options minimum: 1
    config.merge_validates_format_of_email_field_options with: /@/
    config.crypto_provider = Authlogic::CryptoProviders::BCrypt
  end
  
  # Additional validations (optional)
  validates :login, presence: true, uniqueness: true, length: { minimum: 3 }
  validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
end

Creating UserSession Model

# app/models/user_session.rb
class UserSession < Authlogic::Session::Base
  # Customize session settings
  find_by_login_method :find_by_login_or_email
  remember_me_for 2.weeks
  
  # Hook methods (optional)
  def to_key
    new_record? ? nil : [send(self.class.primary_key)]
  end
  
  def persisted?
    false
  end
end

Authentication in Controllers

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  helper_method :current_user_session, :current_user
  
  private
  
  def current_user_session
    return @current_user_session if defined?(@current_user_session)
    @current_user_session = UserSession.find
  end
  
  def current_user
    return @current_user if defined?(@current_user)
    @current_user = current_user_session&.user
  end
  
  def require_user
    unless current_user
      store_location
      flash[:notice] = "You must be logged in to access this page"
      redirect_to new_user_session_url
      return false
    end
  end
  
  def require_no_user
    if current_user
      store_location
      flash[:notice] = "You must be logged out to access this page"
      redirect_to account_url
      return false
    end
  end
  
  def store_location
    session[:return_to] = request.url
  end
  
  def redirect_back_or_default(default)
    redirect_to(session[:return_to] || default)
    session[:return_to] = nil
  end
end

Login Processing (UserSessionsController)

# app/controllers/user_sessions_controller.rb
class UserSessionsController < ApplicationController
  before_action :require_no_user, only: [:new, :create]
  before_action :require_user, only: :destroy
  
  def new
    @user_session = UserSession.new
  end
  
  def create
    @user_session = UserSession.new(user_session_params)
    if @user_session.save
      flash[:notice] = "Login successful!"
      redirect_back_or_default account_url
    else
      render :new
    end
  end
  
  def destroy
    current_user_session.destroy
    flash[:notice] = "Logout successful!"
    redirect_back_or_default new_user_session_url
  end
  
  private
  
  def user_session_params
    params.require(:user_session).permit(:login, :password, :remember_me)
  end
end

User Registration (UsersController)

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :require_no_user, only: [:new, :create]
  before_action :require_user, only: [:show, :edit, :update]
  
  def new
    @user = User.new
  end
  
  def create
    @user = User.new(user_params)
    
    if @user.save
      flash[:notice] = "Account registered!"
      redirect_back_or_default account_url
    else
      render :new
    end
  end
  
  def show
    @user = current_user
  end
  
  def edit
    @user = current_user
  end
  
  def update
    @user = current_user
    
    if @user.update(user_params)
      flash[:notice] = "Account updated!"
      redirect_to account_url
    else
      render :edit
    end
  end
  
  private
  
  def user_params
    params.require(:user).permit(:login, :email, :password, :password_confirmation)
  end
end

Migration Example

# db/migrate/create_users.rb
class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      t.string :login,               null: false
      t.string :email,               null: false
      t.string :crypted_password,    null: false
      t.string :password_salt,       null: false
      t.string :persistence_token,   null: false
      t.string :single_access_token, null: false
      t.string :perishable_token,    null: false
      
      # Magic columns, just like ActiveRecord's created_at and updated_at
      t.integer :login_count,        null: false, default: 0
      t.integer :failed_login_count, null: false, default: 0
      t.datetime :last_request_at
      t.datetime :current_login_at
      t.datetime :last_login_at
      t.string :current_login_ip
      t.string :last_login_ip
      
      t.timestamps null: false
    end
    
    add_index :users, :login
    add_index :users, :email
    add_index :users, :persistence_token
    add_index :users, :single_access_token
    add_index :users, :perishable_token
  end
end