Yauth is a extremely simple authentication solution for prototypes, and provides a drop-in solution for http basic authentication. It uses a yaml file to store usernames and hashed password combined with the http basic authentication. The whole gem provides a better-than-nothing security, and it was designed with small prototypes in mind. It is entirely developed as a github.com/hassox/warden strategy, the same library on which the popular Devise is based.
Yauth resolves one well defined problem: protecting a web application that is going to be accessed by a few users. As adding new users requires manual intervention (only launching a command, see below), it’s a good choice for single-users web applications or prototypes. In this way you can password-protect your app easily and expose it to your clients on the web.
First, install the gem:
gem install yauth
Or if you are using Bundler:
echo "gem 'yauth'" >> Gemfile bundle install
Add the first user (username ‘bar’ and password ‘foo’):
yauth add bar foo
Check the ‘config/users.yml’ into your version control system:
git add config/users.yml git commit -m "Added user 'bar'."
Yauth requires almost no configuration, 5 lines of code.
In your application.rb, simply put:
Yauth::Strategy.install! use Warden::Manager do |manager| manager.default_strategies :yauth_users manager.failure_app = Yauth::FailureApp.new("Your Realm") end
To require authentication inside an action, simply call:
get '/' do request.env['warden'].authenticate! # execution stop and auth is required "hello world\n" end
In your config/application.rb file put:
Yauth::Strategy.install! config.middleware.use Warden::Manager do |manager| manager.default_strategies :yauth_users manager.failure_app = Yauth::FailureApp.new("Your Realm") end
To require authentication inside an action, add this method to app/controllers/application_controller.rb:
private def authenticate env['warden'].authenticate! end
Then, you can use the authenticate
method as a before filter for every method that requires authentication:
before_filter :authenticate, :only => :your_method_here
If you want to add the user ‘foo’, with password ‘bar’, just launch:
yauth add foo bar
Then, if you want to change ‘foo’ password to ‘oof’, just launch:
yauht add foo oof
Finally, to remove ‘foo’ user:
yauth rm foo
Users are stored in the ‘config/users.yml’ file, with the password stored using BCrypt (github.com/codahale/bcrypt-ruby). In this way it’s safe to add the ‘config/users.yml’ to the version control system.
You can see an example of the ‘config/users.yml’ file:
--- - user: username: admin password: !str:BCrypt::Password str: $2a$10$UMR/fB5Jn5oRNe.OV9VicOLrg9BnPyN6Vc3S/noI5LWzfMKK2Zj0q "@checksum": Lrg9BnPyN6Vc3S/noI5LWzfMKK2Zj0q "@cost": 10 "@salt": $2a$10$UMR/fB5Jn5oRNe.OV9VicO "@version": !str:BCrypt::Password 2a
YOU MUST RECREATE your users.yml file when migrating from 0.1 to 0.2, as I changed the encryption function to BCrypt. Unfortunately it’s pretty cheap to crack a password encrypted inside an hash, as stated in this article: codahale.com/how-to-safely-store-a-password. And one of the main goals of this project it’s to store passwords securely. Beware that it might be slower to compute, but it is much safer with BCrypt.
This has been done thanks to Gabriele Renzi, that has pointed me in the right direction.
Future versions will include:
-
drop-in api key solution, i.e. user might have a key for API prototypation;
-
hash function independence;
-
authentication scopes, as defined in warden.
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
-
Fork the project
-
Start a feature/bugfix branch
-
Commit and push until you are happy with your contribution
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright © 2011 Matteo Collina. See LICENSE.txt for further details.