Better Auth Rails
Rails adapter for Better Auth Ruby. Provides seamless integration with Ruby on Rails applications including middleware, controller helpers, and generators.
Installation
Add this line to your application's Gemfile:
gem "better_auth-rails"
Defensive alias package
better_auth_rails is published only as a defensive alias package.
WARNING: This gem is an alias. Use better_auth-rails.
And then execute:
bundle install
Usage
Basic Setup
Add to your config/application.rb:
require "better_auth/rails"
Compatibility require is also supported:
require "better_auth_rails"
Or in your Gemfile:
gem "better_auth-rails", require: "better_auth/rails"
Initializer And Migration
Create the default initializer and base migration:
bin/rails generate better_auth:install
The same install path is available as a Rails task:
bin/rails better_auth:init
To generate only the base migration:
bin/rails generate better_auth:migration
bin/rails better_auth:generate:migration
The generators skip an existing config/initializers/better_auth.rb or existing *_create_better_auth_tables.rb migration instead of overwriting them.
Configuration
The install generator creates config/initializers/better_auth.rb:
BetterAuth::Rails.configure do |config|
config.secret =
Rails.application.credentials.dig(:better_auth, :secret) ||
Rails.application.credentials.secret_key_base ||
Rails.application.secret_key_base
config.base_url = ENV["BETTER_AUTH_URL"]
config.base_path = "/api/auth"
config.database = ->() { BetterAuth::Rails::ActiveRecordAdapter.new() }
config.trusted_origins = [
ENV["BETTER_AUTH_URL"]
].compact
config.session = {
cookie_cache: {
enabled: true,
max_age: 5 * 60,
strategy: "jwe"
}
}
config.advanced = {
ip_address: {
ip_address_headers: ["x-forwarded-for"],
disable_ip_tracking: false
}
}
config.experimental = {
joins: false
}
config. = {
# github: BetterAuth::SocialProviders.github(
# client_id: ENV.fetch("GITHUB_CLIENT_ID"),
# client_secret: ENV.fetch("GITHUB_CLIENT_SECRET")
# )
}
config.plugins = []
config.hooks = {
before: [],
after: []
}
end
Rails configuration is a thin option builder for the core Rack auth object. The same option concepts are available in core Ruby through BetterAuth.auth(...); Rails places them in config/initializers/better_auth.rb so applications can rely on credentials, ActiveRecord, and Rails environment configuration.
The ActiveRecord adapter uses whichever database adapter the Rails app is already configured with, including PostgreSQL and MySQL.
JavaScript Client
Ruby Better Auth exposes the same HTTP route surface. Frontend apps should use the upstream Better Auth JavaScript client and point it at the Ruby server:
import { createAuthClient } from "better-auth/client";
export const authClient = createAuthClient({
baseURL: "http://localhost:3000",
basePath: "/api/auth",
});
Plugin schemas are included in generated migrations through the same configuration:
require "better_auth/api_key"
BetterAuth::Rails.configure do |config|
config.plugins = [
BetterAuth::Plugins.api_key
]
end
# Then regenerate before migrating if this is a new app:
# bin/rails generate better_auth:migration
Routes
Mount the Better Auth Rack app in your routes:
Rails.application.routes.draw do
better_auth
end
By default this mounts at /api/auth. Rails mounts the core Rack auth app through a small wrapper so Better Auth still sees the full auth path after Rails moves the mount prefix into SCRIPT_NAME. To customize the path:
Rails.application.routes.draw do
better_auth at: "/auth"
end
The Better Auth core router handles internal routes such as /callback/:providerId.
Controller Helpers
Include the controller helpers in your ApplicationController:
class ApplicationController < ActionController::Base
include BetterAuth::Rails::ControllerHelpers
end
Now you have access to authentication methods:
class PostsController < ApplicationController
before_action :require_authentication
def index
@user = current_user
end
end
Available Methods
current_session- Returns the current Better Auth session hashcurrent_user- Returns the current Better Auth user hashauthenticated?- Returns true when a user is presentrequire_authentication- Halts withhead :unauthorizedand returnsfalsewhen no user is present
Development
Full documentation is being adapted in the root docs/ app. The Rails guide lives at docs/content/docs/integrations/rails.mdx; pages with a Ruby port warning still contain upstream TypeScript examples for reference.
Setup
# Clone the monorepo
git clone --recursive https://github.com/sebasxsala/better-auth.git
cd better-auth/packages/better_auth-rails
# Install dependencies
bundle install
Running Tests
# Run all tests
rbenv exec bundle exec rspec
# Run with coverage
COVERAGE=true rbenv exec bundle exec rspec
# Run specific test
rbenv exec bundle exec rspec spec/better_auth/rails/controller_helpers_spec.rb
Code Style
We use StandardRB for linting:
# Check style
RUBOCOP_CACHE_ROOT=/private/var/folders/7x/jrsz946d2w73n42fb1_ff5000000gn/T/rubocop_cache_rails rbenv exec bundle exec standardrb
# Auto-fix issues
RUBOCOP_CACHE_ROOT=/private/var/folders/7x/jrsz946d2w73n42fb1_ff5000000gn/T/rubocop_cache_rails rbenv exec bundle exec standardrb --fix
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/sebasxsala/better-auth.
When contributing:
- Fork the repository
- Create your feature branch (
git checkout -b feat/amazing-feature) - Make sure tests pass (
bundle exec rspec) - Ensure code style passes (
bundle exec standardrb) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request towards the
canarybranch
License
The gem is available as open source under the terms of the MIT License.