Just a little announcement about something I cooked up this afternoon. It’s
nothing ground-breaking but might save you a little time. Basically, I was
getting super-tired of writing the same authentication code for every project so
I extracted it into a plugin called has_password
. Install like so:
ruby script/plugin install git://github.com/jcoglan/has_password
Now, this plugin is tiny and does almost nothing for you, but that’s kind of the
point. All I wanted was a simple way to reuse all the password-hashing stuff,
not something to generate migrations and controller code. So, all has_password
does is abstract out the idea of a model class being password-protected and
storing hashed passwords and salts. To use it:
class User < ActiveRecord::Base
has_password :salt_size => 16
end
Your model should have password_hash
and password_salt
fields. Hashes are
160-bit (40-char) SHA1 hashes and salts are random hexadecimal strings of the
bit-length you specify (16 bits gives you 4 hex digits). Your model will gain
three methods:
user.password=(pwd)
: sets the hash and salt values of user
from the given
plain-text value pwd
. The plain-text password is stored in user
while in
memory but is not persisted to the database.
user.password
returns the current plain-text password if one has been set
since user
was pulled from the database. An object freshly pulled from the DB
will return nil
for this method.
user.has_password?(pwd)
: returns true
iff user
’s plain-text password is
equal to pwd
.
Finally, you get a callback in case you want to do stuff like send password confirmation emails. In your model class, put, for example:
after_password_change :send_notification
or
after_password_change do |model|
UserMailer::deliver_email_notification(model)
end
In terms of validation, it automatically validates_confirmation_of :password
and checks supplied passwords for a few obvious silly phrases like, say,
password
and test
. Passwords are only validated if password
is non-blank.
Give it a whirl, and do let me know if you find any bugs.