This widely-used plugin provides a foundation for securely managing user authentication:
- Login / logout
- Secure password handling
- Account activation by validating email
- Account approval / disabling by admin
- Rudimentary hooks for authorization and access control.
Several features were updated in May, 2008.
- Stable newer version
- ‘Classic’ (backward-compatible) version
- Experimental version (Much more modular, needs testing & review)
> IMPORTANT: if you upgrade your site, existing user account > passwords will stop working unless you use —old-passwords
- Issue Tracker
Please submit any bugs or annoyances on the lighthouse tracker at
For anything simple enough, please github message both maintainers: Rick Olson (technoweenie) and Flip Kromer (mrflip).
- Documentation
This page has notes on
See the wiki (or the notes/ directory) if you want to learn more about:
- Extensions, Addons and Alternatives such as HAML templates
- Security Design Patterns with snazzy diagram
- Authentication — Lets a visitor identify herself (and lay claim to her corresponding Roles and measure of Trust)
- Trust Metrics — Confidence we can rely on the outcomes of this visitor’s actions.
- Authorization and Policy — Based on trust and identity, what actions may this visitor perform?
- Access Control — How the Authorization policy is actually enforced in your code (A: hopefully without turning it into a spaghetti of if thens)
- Rails Plugins for Authentication, Trust, Authorization and Access Control
- Tradeoffs — for the paranoid or the curious, a rundown of tradeoffs made in the code
- CHANGELOG — Summary of changes to internals
- TODO — Ideas for how you can help
These best version of the release notes are in the notes/ directory in the source code — look there for the latest version. The wiki versions are taken (manually) from there.
- Exciting new features
- Stories
There are now Cucumber features that allow expressive, enjoyable tests for the authentication code. The flexible code for resource testing in stories was extended from Ben Mabey’s.
- Modularize to match security design patterns:
- Authentication (currently: password, browser cookie token, HTTP basic)
- Trust metric (email validation)
- Authorization (stateful roles)
- Leave a flexible framework that will play nicely with other access control / policy definition / trust metric plugins
- Other
- Added a few helper methods for linking to user pages
- Uniform handling of logout, remember_token
- Stricter email, login field validation
- Minor security fixes — see CHANGELOG
- Non-backwards compatible Changes
Here are a few changes in the May 2008 release that increase “Defense in Depth” but may require changes to existing accounts
- If you have an existing site, none of these changes are compelling enough to warrant migrating your userbase.
- If you are generating for a new site, all of these changes are low-impact. You should apply them.
- Passwords
The new password encryption (using a site key salt and stretching) will break existing user accounts’ passwords. We recommend you use the —old-passwords option or write a migration tool and submit it as a patch. See the [[Tradeoffs]] note for more information.
- Validations
By default, email and usernames are validated against a somewhat strict pattern; your users’ values may be now illegal. Adjust to suit.
- Installation
This is a basic restful authentication generator for rails, taken from acts as authenticated. Currently it requires Rails 1.2.6 or above.
IMPORTANT FOR RAILS > 2.1 USERS To avoid a NameError
exception (lighthouse tracker ticket), check out the code to have an underscore and not dash in its name:
- either use
git clone git://github.com/technoweenie/restful-authentication.git restful_authentication
- or rename the plugin’s directory to be
restful_authentication
after fetching it.
To use the generator:
./script/generate authenticated user sessions \ —include-activation \ —stateful \ —rspec \ —skip-migration \ —skip-routes \ —old-passwords- The first parameter specifies the model that gets created in signup (typically a user or account model). A model with migration is created, as well as a basic controller with the create method. You probably want to say “User” here.
- The second parameter specifies the session controller name. This is the controller that handles the actual login/logout function on the site. (probably: “Session”).
- —include-activation: Generates the code for a ActionMailer and its respective Activation Code through email.
-stateful: Builds in support for acts_as_state_machine and generates activation code. (@-stateful@ implies--include-activation
). Based on the idea at [[http://www.vaporbase.com/postings/stateful_authentication]]. Passing--skip-migration
will skip the user migration, and--skip-routes
will skip resource generation- both useful if you’ve already run this generator. (Needs the acts_as_state_machine plugin, but new installs should probably run with @-aasm@ instead.)
- —aasm: Works the same as stateful but uses the updated aasm gem
- —rspec: Generate RSpec tests and Stories in place of standard rails tests. This requires the RSpec and Rspec-on-rails plugins (make sure you “./script/generate rspec” after installing RSpec.) The rspec and story suite are much more thorough than the rails tests, and changes are unlikely to be backported.
- —old-passwords: Use the older password scheme (see [[#COMPATIBILITY]], above)
- —skip-migration: Don’t generate a migration file for this model
- —skip-routes: Don’t generate a resource line in
config/routes.rb
- After installing
The below assumes a Model named ‘User’ and a Controller named ‘Session’; please
alter to suit. There are additional security minutae in notes/README-Tradeoffs
— only the paranoid or the curious need bother, though.
- Add these familiar login URLs to your
config/routes.rb
if you like:
map.signup ‘/signup’, :controller => ‘users’, :action => ‘new’
map.login ‘/login’, :controller => ‘session’, :action => ‘new’
map.logout ‘/logout’, :controller => ‘session’, :action => ‘destroy’
- With
--include-activation
, also add to yourconfig/routes.rb
:
map.activate ‘/activate/:activation_code’, :controller => ‘users’, :action => ‘activate’, :activation_code => nil
and add an observer to config/environment.rb
:
config.active_record.observers = :user_observer
Pay attention, may be this is not an issue for everybody, but if you should
have problems, that the sent activation_code does match with that in the
database stored, reload your user object before sending its data through email
something like:
class UserObserver < ActiveRecord::Observer
def after_create(user)
user.reload
UserMailer.deliver_signup_notification(user)
end
def after_save(user)
user.reload
UserMailer.deliver_activation(user) if user.recently_activated?
end
end
- With
--stateful
, add an observer to config/environment.rb:
config.active_record.observers = :user_observer
and modify the users resource line to read
map.resources :users, :member => { :suspend => :put,
:unsuspend => :put,
:purge => :delete }
- If you use a public repository for your code (such as github, rubyforge, gitorious, etc.) make sure to NOT post your site_keys.rb (add a line like ‘/config/initializers/site_keys.rb’ to your .gitignore or do the svn ignore dance), but make sure you DO keep it backed up somewhere safe.