Top Related Projects
Flexible authentication solution for Rails with Warden.
OmniAuth is a flexible authentication system utilizing Rack middleware.
Forms made easy for Rails! It's tied to a simple DSL, with no opinion on markup.
Authorization Gem for Ruby on Rails.
Minimal authorization through OO design and pure Ruby classes
A simple ruby authentication solution.
Quick Overview
Clearance is a Rails engine for handling user authentication. It provides a simple and secure way to add sign up, sign in, and sign out functionality to your Rails application. Clearance is designed to be lightweight, flexible, and easy to customize.
Pros
- Simple and straightforward implementation
- Secure by default, with features like password hashing and secure cookie handling
- Easy to customize and extend
- Well-documented and maintained by thoughtbot
Cons
- Limited built-in features compared to more comprehensive authentication solutions
- May require additional work for complex authentication scenarios
- Tied specifically to Rails, not suitable for other frameworks or languages
- Less active community compared to some alternatives
Code Examples
- Basic user model setup:
class User < ApplicationRecord
include Clearance::User
end
- Customizing password requirements:
class User < ApplicationRecord
include Clearance::User
validates :password, length: { minimum: 8 }, if: -> { password.present? }
end
- Adding custom fields to sign up form:
class UsersController < Clearance::UsersController
private
def user_params
params.require(:user).permit(:email, :password, :name)
end
end
- Restricting access to authenticated users:
class ApplicationController < ActionController::Base
include Clearance::Controller
before_action :require_login
end
Getting Started
- Add Clearance to your Gemfile:
gem "clearance"
- Run the installation generator:
rails generate clearance:install
- Run migrations:
rails db:migrate
- Add Clearance routes to your
config/routes.rb
:
Rails.application.routes.draw do
# ... other routes ...
# Add Clearance routes
resources :passwords, controller: "clearance/passwords", only: [:create, :new]
resource :session, controller: "clearance/sessions", only: [:create]
resources :users, controller: "clearance/users", only: [:create] do
resource :password, controller: "clearance/passwords", only: [:edit, :update]
end
get "/sign_in" => "clearance/sessions#new", as: "sign_in"
delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
get "/sign_up" => "clearance/users#new", as: "sign_up"
end
With these steps, you'll have basic authentication functionality in your Rails application. Customize as needed for your specific requirements.
Competitor Comparisons
Flexible authentication solution for Rails with Warden.
Pros of Devise
- More feature-rich with built-in modules for various authentication scenarios
- Highly customizable with extensive configuration options
- Large community and ecosystem with many extensions and plugins
Cons of Devise
- Can be complex and overwhelming for simple authentication needs
- Heavier footprint and potential performance impact due to its extensive features
- Steeper learning curve for beginners
Code Comparison
Devise configuration:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
Clearance configuration:
include Clearance::User
Summary
Devise offers a comprehensive authentication solution with numerous features and customization options, making it suitable for complex applications. However, this comes at the cost of increased complexity and potential performance overhead.
Clearance, on the other hand, provides a simpler, lightweight authentication solution that's easier to set up and maintain. It's ideal for projects with straightforward authentication requirements but may lack some advanced features offered by Devise.
The choice between the two depends on the specific needs of your project, balancing between feature richness and simplicity.
OmniAuth is a flexible authentication system utilizing Rack middleware.
Pros of OmniAuth
- Supports multiple authentication providers (e.g., Google, Facebook, Twitter)
- Highly flexible and customizable for various authentication strategies
- Large community and extensive plugin ecosystem
Cons of OmniAuth
- Requires more setup and configuration compared to Clearance
- Can be overwhelming for simple authentication needs
- Potential security risks if not properly implemented
Code Comparison
Clearance (user authentication):
class User < ApplicationRecord
include Clearance::User
end
OmniAuth (authentication strategy setup):
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
end
Summary
Clearance is a simpler, more straightforward authentication solution for Rails applications, focusing on email and password authentication. It's easier to set up and maintain for basic authentication needs.
OmniAuth, on the other hand, offers a more versatile approach, allowing integration with various third-party authentication providers. It's more suitable for applications requiring multiple authentication options or social media login capabilities.
The choice between the two depends on the specific requirements of your project, with Clearance being ideal for simpler needs and OmniAuth for more complex authentication scenarios.
Forms made easy for Rails! It's tied to a simple DSL, with no opinion on markup.
Pros of Simple Form
- More flexible and customizable form building
- Supports a wider range of form input types and styles
- Integrates well with various CSS frameworks and design systems
Cons of Simple Form
- Focuses solely on form generation, lacking authentication features
- May require additional setup and configuration for complex forms
- Can add unnecessary complexity for simple form needs
Code Comparison
Simple Form:
<%= simple_form_for @user do |f| %>
<%= f.input :username %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
Clearance:
<%= form_for @user do |form| %>
<%= form.label :email %>
<%= form.email_field :email %>
<%= form.label :password %>
<%= form.password_field :password %>
<%= form.submit %>
<% end %>
Summary
Simple Form excels in creating complex, customizable forms with various input types and styles. It integrates well with different CSS frameworks but focuses solely on form generation. Clearance, on the other hand, provides a complete authentication solution with a simpler form-building approach. Simple Form may require more setup for complex forms, while Clearance offers a more straightforward implementation for basic authentication needs. The choice between the two depends on the project's specific requirements for form complexity and authentication features.
Authorization Gem for Ruby on Rails.
Pros of CanCan
- More flexible and granular authorization system
- Supports role-based and attribute-based access control
- Easier to define complex authorization rules
Cons of CanCan
- Steeper learning curve for beginners
- Can become complex for large applications with many roles
- Requires more setup and configuration
Code Comparison
CanCan:
class Ability
include CanCan::Ability
def initialize(user)
can :read, Post
can :manage, Post, user_id: user.id
end
end
Clearance:
class PostsController < ApplicationController
before_action :require_login, except: [:index, :show]
def create
@post = current_user.posts.build(post_params)
# ...
end
end
CanCan focuses on defining abilities and permissions, while Clearance provides a simpler authentication-based approach. CanCan offers more flexibility in defining complex authorization rules, but Clearance is easier to set up and use for basic authentication needs.
Minimal authorization through OO design and pure Ruby classes
Pros of Pundit
- Flexible and customizable authorization system
- Integrates well with existing Rails applications
- Encourages separation of authorization logic into policy objects
Cons of Pundit
- Requires more setup and configuration compared to Clearance
- May have a steeper learning curve for beginners
- Focuses solely on authorization, not authentication
Code Comparison
Pundit:
class PostPolicy
def initialize(user, post)
@user = user
@post = post
end
def update?
@user.admin? || @post.author == @user
end
end
Clearance:
class PostsController < ApplicationController
before_action :require_login
def update
@post = Post.find(params[:id])
if current_user.admin? || @post.author == current_user
# Update logic here
else
redirect_to root_path, alert: "Not authorized"
end
end
end
Pundit focuses on separating authorization logic into policy objects, while Clearance typically handles authorization within controllers. Pundit offers more flexibility and scalability for complex authorization scenarios, whereas Clearance provides a simpler, more straightforward approach that may be sufficient for smaller applications.
A simple ruby authentication solution.
Pros of Authlogic
- More flexible and customizable authentication solution
- Supports multiple authentication methods (e.g., email, username)
- Extensive configuration options for advanced use cases
Cons of Authlogic
- Steeper learning curve due to its flexibility
- Less opinionated, requiring more setup and configuration
- Not actively maintained (last update in 2019)
Code Comparison
Authlogic:
class UserSession < Authlogic::Session::Base
# Configuration options here
end
class User < ApplicationRecord
acts_as_authentic do |c|
c.crypto_provider = Authlogic::CryptoProviders::BCrypt
end
end
Clearance:
class User < ApplicationRecord
include Clearance::User
end
# In config/initializers/clearance.rb
Clearance.configure do |config|
config.mailer_sender = "reply@example.com"
end
Key Differences
- Authlogic provides more granular control over authentication processes but requires more setup.
- Clearance offers a simpler, more opinionated approach with less configuration needed.
- Clearance is actively maintained and follows modern Ruby on Rails best practices.
- Authlogic allows for easier integration with legacy systems or custom authentication requirements.
Both libraries provide solid authentication solutions, but Clearance is generally recommended for new projects due to its active maintenance and ease of use, while Authlogic may be preferred for projects requiring highly customized authentication flows.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Clearance
Rails authentication with email & password.
Clearance is intended to be small, simple, and well-tested. It has opinionated defaults but is intended to be easy to override.
Please use GitHub Issues to report bugs. If you have a question about the
library, please use the clearance
tag on Stack Overflow. This tag is
monitored by contributors.
Getting Started
Clearance is a Rails engine tested against Rails >= 6.1
and Ruby >= 3.0.0
.
You can add it to your Gemfile with:
gem "clearance"
Run the bundle command to install it.
After you install Clearance, you need to run the generator:
rails generate clearance:install
The Clearance install generator:
- Inserts
Clearance::User
into yourUser
model - Inserts
Clearance::Controller
into yourApplicationController
- Creates an initializer file to allow further configuration.
- Creates a migration file that either create a users table or adds any necessary columns to the existing table.
Configure
Override any of these defaults in config/initializers/clearance.rb
:
Clearance.configure do |config|
config.allow_sign_up = true
config.allow_password_reset = true
config.cookie_domain = ".example.com"
config.cookie_expiration = lambda { |cookies| 1.year.from_now.utc }
config.cookie_name = "remember_token"
config.cookie_path = "/"
config.routes = true
config.httponly = true
config.mailer_sender = "reply@example.com"
config.password_strategy = Clearance::PasswordStrategies::BCrypt
config.redirect_url = "/"
config.url_after_destroy = nil
config.url_after_denied_access_when_signed_out = nil
config.rotate_csrf_on_sign_in = true
config.same_site = nil
config.secure_cookie = Rails.configuration.force_ssl
config.signed_cookie = false
config.sign_in_guards = []
config.user_model = "User"
config.parent_controller = "ApplicationController"
config.sign_in_on_password_reset = false
end
Use
Access Control
Use the require_login
filter to control access to controller actions.
class ArticlesController < ApplicationController
before_action :require_login
def index
current_user.articles
end
end
Clearance also provides routing constraints that can be used to control access at the routing layer:
Blog::Application.routes.draw do
constraints Clearance::Constraints::SignedIn.new { |user| user.admin? } do
root to: "admin/dashboards#show", as: :admin_root
end
constraints Clearance::Constraints::SignedIn.new do
root to: "dashboards#show", as: :signed_in_root
end
constraints Clearance::Constraints::SignedOut.new do
root to: "marketing#index"
end
end
Helper Methods
Use current_user
, signed_in?
, and signed_out?
in controllers, views, and
helpers. For example:
<% if signed_in? %>
<%= current_user.email %>
<%= button_to "Sign out", sign_out_path, method: :delete %>
<% else %>
<%= link_to "Sign in", sign_in_path %>
<% end %>
Password Resets
When a user resets their password, Clearance delivers them an email. You
should change the mailer_sender
default, used in the email's "from" header:
Clearance.configure do |config|
config.mailer_sender = "reply@example.com"
end
Multiple Domain Support
You can support multiple domains, or other special domain configurations by
optionally setting cookie_domain
as a callable object. The first argument
passed to the method is an ActionDispatch::Request object.
Clearance.configure do |config|
config.cookie_domain = lambda { |request| request.host }
end
Integrating with Rack Applications
Clearance adds its session to the Rack environment hash so middleware and other Rack applications can interact with it:
class Bubblegum::Middleware
def initialize(app)
@app = app
end
def call(env)
if env[:clearance].signed_in?
env[:clearance].current_user.bubble_gum
end
@app.call(env)
end
end
Overriding Clearance
Routes
See config/routes.rb for the default set of routes.
As of Clearance 1.5 it is recommended that you disable Clearance routes and take full control over routing and URL design. This ensures that your app's URL design won't be affected if the gem's routes and URL design are changed.
To disable the routes, change the routes
configuration option to false:
Clearance.configure do |config|
config.routes = false
end
You can optionally run rails generate clearance:routes
to dump a copy of the
default routes into your application for modification.
Controllers
See app/controllers/clearance for the default behavior. Many protected methods were extracted in these controllers in an attempt to make overrides and hooks simpler.
To override a Clearance controller, subclass it and update the routes to point to your new controller (see the "Routes" section).
class PasswordsController < Clearance::PasswordsController
class SessionsController < Clearance::SessionsController
class UsersController < Clearance::UsersController
Redirects
The post-action redirects in Clearance are simple methods which can be overridden one by one, or configured globally.
These "success" methods are called for signed in users, and redirect to
Clearance.configuration.redirect_url
(which is /
by default):
passwords#url_after_update
sessions#url_after_create
sessions#url_for_signed_in_users
users#url_after_create
application#url_after_denied_access_when_signed_in
To override them all at once, change the global configuration of redirect_url
.
To change individual URLs, override the appropriate method in your subclassed
controller.
These "failure" methods are called for signed out sessions:
application#url_after_denied_access_when_signed_out
sessions#url_after_destroy
You can override the appropriate method in your subclassed controller or you can set a configuration value for either of these URLs:
Clearance.configuration.url_after_denied_access_when_signed_out
Clearance.configuration.url_after_destroy
Both configurations default to nil
and if not set will default to
sign_in_url
in sessions_controller.rb
and authorization.rb
for backwards
compatibility.
Views
See app/views for the default behavior.
To override a view, create your own copy of it:
app/views/clearance_mailer/change_password.html.erb
app/views/passwords/create.html.erb
app/views/passwords/edit.html.erb
app/views/passwords/new.html.erb
app/views/sessions/_form.html.erb
app/views/sessions/new.html.erb
app/views/users/_form.html.erb
app/views/users/new.html.erb
You can use the Clearance views generator to copy the default views to your application for modification.
rails generate clearance:views
Layouts
By default, Clearance uses your application's default layout. If you would like
to change the layout that Clearance uses when rendering its views, simply
specify the layout in the config/application.rb
config.to_prepare do
Clearance::PasswordsController.layout "my_passwords_layout"
Clearance::SessionsController.layout "my_sessions_layout"
Clearance::UsersController.layout "my_admin_layout"
end
Translations
All flash messages and email subject lines are stored in i18n translations. Override them like any other translation.
See config/locales/clearance.en.yml for the default behavior.
You can also install clearance-i18n for access to additional, user-contributed translations.
User Model
See lib/clearance/user.rb for the default behavior. You can override those methods as needed.
Note that there are some model-level validations (see above link for detail)
which the Clearance::User
module will add to the configured model class and
which may conflict with or duplicate already present validations on the email
and password
attributes. Over-riding the email_optional?
or
skip_password_validation?
methods to return true
will disable those
validations from being added.
Signed Cookies
By default, Clearance uses unsigned cookies. If you would like to use signed cookies you can do so by overriding the default in an initializer like so:
Clearance.configure do |config|
# ... other overrides
config.signed_cookie = true
end
If you are currently not using signed cookies but would like to migrate your
users over to them without breaking current sessions, you can do so by passing
in :migrate
rather than true
as so:
Clearance.configure do |config|
# ... other overrides
config.signed_cookie = :migrate
end
You can read more about signed cookies in Clearance and why they are a good idea in the pull request that added them.
Extending Sign In
By default, Clearance will sign in any user with valid credentials. If you need to support additional checks during the sign in process then you can use the SignInGuard stack. For example, using the SignInGuard stack, you could prevent suspended users from signing in, or require that users confirm their email address before accessing the site.
SignInGuard
s offer fine-grained control over the process of
signing in a user. Each guard is run in order and hands the session off to
the next guard in the stack.
A SignInGuard
is an object that responds to call
. It is initialized with a
session and the current stack.
On success, a guard should call the next guard or return SuccessStatus.new
if
you don't want any subsequent guards to run.
On failure, a guard should call FailureStatus.new(failure_message)
. It can
provide a message explaining the failure.
For convenience, a SignInGuard class has been
provided and can be inherited from. The convenience class provides a few methods
to help make writing guards simple: success
, failure
, next_guard
,
signed_in?
, and current_user
.
Here's an example custom guard to handle email confirmation:
Clearance.configure do |config|
config.sign_in_guards = ["EmailConfirmationGuard"]
end
# app/guards/email_confirmation_guard.rb
class EmailConfirmationGuard < Clearance::SignInGuard
def call
if unconfirmed?
failure("You must confirm your email address.")
else
next_guard
end
end
def unconfirmed?
signed_in? && !current_user.confirmed_at
end
end
Testing
Fast Feature Specs
Clearance includes middleware that avoids wasting time spent visiting, loading, and submitting the sign in form. It instead signs in the designated user directly. The speed increase can be substantial.
Enable the Middleware in Test:
# config/environments/test.rb
MyRailsApp::Application.configure do
# ...
config.middleware.use Clearance::BackDoor
# ...
end
Usage:
visit root_path(as: user)
Additionally, if User#to_param
is overridden, you can pass a block in
order to override the default behavior:
# config/environments/test.rb
MyRailsApp::Application.configure do
# ...
config.middleware.use Clearance::BackDoor do |username|
Clearance.configuration.user_model.find_by(username: username)
end
# ...
end
Ready Made Feature Specs
If you're using RSpec, you can generate feature specs to help prevent
regressions in Clearance's integration with your Rails app over time. These
feature specs, will also require factory_bot_rails
.
To Generate the clearance specs, run:
rails generate clearance:specs
Controller Test Helpers
To test controller actions that are protected by before_action :require_login
,
require Clearance's test helpers in your test suite.
For rspec
, add the following line to your spec/rails_helper.rb
or
spec/spec_helper
if rails_helper
does not exist:
require "clearance/rspec"
For test-unit
, add this line to your test/test_helper.rb
:
require "clearance/test_unit"
Note for Rails 5: the default generated controller tests are now integration tests. You will need to use the backdoor middleware instead.
This will make Clearance::Controller
methods work in your controllers
during functional tests and provide access to helper methods like:
sign_in
sign_in_as(user)
sign_out
View and Helper Spec Helpers
Does the view or helper you're testing reference signed_in?
, signed_out?
or
current_user
? If you require 'clearance/rspec'
, you will have the following
helpers available in your view specs:
sign_in
sign_in_as(user)
These will make the clearance view helpers work as expected by signing in either
a new instance of your user model (sign_in
) or the object you pass to
sign_in_as
. If you do not call one of these sign in helpers or otherwise set
current_user
in your view specs, your view will behave as if there is no
current user: signed_in?
will be false and signed_out?
will be true.
Contributing
Please see CONTRIBUTING.md. Thank you, contributors!
Security
For security issues it's better to contact security@thoughtbot.com (See https://thoughtbot.com/security)
License
Clearance is copyright © 2009 thoughtbot. It is free software, and may be
redistributed under the terms specified in the LICENSE
file.
About thoughtbot
This repo is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.
We love open source software! See our other projects. We are available for hire.
Top Related Projects
Flexible authentication solution for Rails with Warden.
OmniAuth is a flexible authentication system utilizing Rack middleware.
Forms made easy for Rails! It's tied to a simple DSL, with no opinion on markup.
Authorization Gem for Ruby on Rails.
Minimal authorization through OO design and pure Ruby classes
A simple ruby authentication solution.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot