Show HN: Veri – minimal authentication framework for Rails

4 months ago 6

Gem Version Github Actions badge

Veri is a cookie-based authentication library for Ruby on Rails that provides essential authentication building blocks without imposing business logic. Unlike full-featured solutions, Veri gives you complete control over your authentication flow while handling the complex underlying mechanics of secure password storage and session management.

Key Features:

  • Cookie-based authentication with database-stored sessions
  • Supports multiple password hashing algorithms (argon2, bcrypt, scrypt)
  • Granular session management and control
  • Built-in return path handling
  • User impersonation feature

⚠️ Development Notice
Veri is functional but in early development. Breaking changes may occur in minor releases until v1.0!

Gem Usage:

Community Resources:

Add Veri to your Gemfile:

Install the gem:

Generate the migration for your user model (replace users with your user table name if different):

# For standard integer IDs rails generate veri:authentication users # For UUID primary keys rails generate veri:authentication users --uuid

Run the migration:

If customization is required, configure Veri in an initializer:

# These are the default values; you can change them as needed Veri.configure do |config| config.hashing_algorithm = :argon2 # Password hashing algorithm (:argon2, :bcrypt, or :scrypt) config.inactive_session_lifetime = nil # Session inactivity timeout (nil means sessions never expire due to inactivity) config.total_session_lifetime = 14.days # Maximum session duration regardless of activity config.user_model_name = "User" # Your user model name end

Your user model is automatically extended with password management methods:

# Set or update a password user.update_password("new_password") # Verify a password user.verify_password("submitted_password")

Include the authentication module and configure protection:

class ApplicationController < ActionController::Base include Veri::Authentication with_authentication # Require authentication by default end class PicturesController < ApplicationController skip_authentication only: [:index, :show] # Allow public access to index and show actions end

This is a simplified example of how to use Veri's authentication methods:

class SessionsController < ApplicationController skip_authentication except: [:destroy] def create user = User.find_by(email: params[:email]) if user&.verify_password(params[:password]) log_in(user) redirect_to return_path || dashboard_path else flash.now[:alert] = "Invalid credentials" render :new, status: :unprocessable_entity end end def destroy log_out redirect_to root_path end end

Available methods:

  • current_user - Returns authenticated user or nil
  • logged_in? - Returns true if user is authenticated
  • log_in(user) - Authenticates user and creates session
  • log_out - Terminates current session
  • return_path - Returns path user was accessing before authentication
  • current_session - Returns current authentication session

User Impersonation (Shapeshifting)

Veri provides user impersonation functionality that allows, for example, administrators to temporarily assume another user's identity:

module Admin class ImpersonationController < ApplicationController def create user = User.find(params[:user_id]) current_session.shapeshift(user) redirect_to root_path, notice: "Now viewing as #{user.name}" end def destroy original_user = current_session.true_identity current_session.revert_to_true_identity redirect_to admin_dashboard_path, notice: "Returned to #{original_user.name}" end end end

Available session methods:

  • shapeshift(user) - Assume another user's identity (maintains original identity)
  • revert_to_true_identity - Return to original identity
  • shapeshifted? - Returns true if currently shapeshifted
  • true_identity - Returns original user when shapeshifted, otherwise current user

Controller helper:

  • shapeshifter? - Returns true if the current session is shapeshifted

Override this private method to customize authentication behavior:

class ApplicationController < ActionController::Base include Veri::Authentication with_authentication # ... private # Customize unauthenticated user handling def when_unauthenticated # By default redirects back with a fallback to the root path if the request format is HTML, # otherwise responds with 401 Unauthorized redirect_to login_path end end

Veri stores authentication sessions in the database, providing session management capabilities:

# Get all sessions for a user user.veri_sessions # Get current session in controller current_session
session.identity # => authenticated user session.info # => { # device: "Desktop", # os: "macOS", # browser: "Chrome", # ip_address: "1.2.3.4", # last_seen_at: "2023-10-01 12:00:00" # }
session.active? # Session is active (neither expired nor inactive) session.inactive? # Session exceeded inactivity timeout session.expired? # Session exceeded maximum lifetime
# Terminate a specific session session.terminate # Terminate all sessions for a user Veri::Session.terminate_all(user) # Clean up expired/inactive sessions Veri::Session.prune # All sessions Veri::Session.prune(user) # Specific user's sessions

Access authentication state in your views:

<% if logged_in? %> <p>Welcome, <%= current_user.name %>!</p> <% if shapeshifter? %> <p><em>Currently viewing as <%= current_user.name %> (Original: <%= current_session.true_identity.name %>)</em></p> <%= link_to "Return to Original Identity", revert_path, method: :patch %> <% end %> <%= link_to "Logout", logout_path, method: :delete %> <% else %> <%= link_to "Login", login_path %> <% end %>

Veri doesn't provide test helpers, but you can easily create your own:

Request Specs (Recommended)

module AuthenticationHelpers def log_in(user) password = "test_password" user.update_password(password) post login_path, params: { email: user.email, password: } end def log_out delete logout_path end end # In your spec_helper.rb RSpec.configure do |config| config.include AuthenticationHelpers, type: :request end

Controller Specs (Legacy)

module AuthenticationHelpers def log_in(user) controller.log_in(user) end def log_out controller.log_out end end # In your spec_helper.rb RSpec.configure do |config| config.include AuthenticationHelpers, type: :controller end

Getting Help and Contributing

Have a question or need assistance? Open a discussion in our discussions section for:

  • Usage questions
  • Implementation guidance
  • Feature suggestions

Found a bug? Please create an issue with:

  • A clear description of the problem
  • Steps to reproduce the issue
  • Your environment details (Rails version, Ruby version, etc.)

Ready to contribute? You can:

  • Fix bugs by submitting pull requests
  • Improve documentation
  • Add new features (please discuss first in our discussions section)

Before contributing, please read the contributing guidelines

The gem is available as open source under the terms of the MIT License.

Everyone interacting in the Veri project is expected to follow the code of conduct.

Read Entire Article