Tuesday, August 26, 2008

Easy password hashing in rails 2.1

I was working on a simple authentication system for a new project and got to the point where I needed to hash the password before storing it. I realized that this was a great opportunity to use the new dirty objects functionality that came out in rails 2.1.

First off, a quick explanation of dirty objects. Dirty objects provides the ability to tell what attributes of a model object have changed. For example, given an active record object "foo" with an attribute "bar", dirty objects adds a method "foo.bar_changed?" which returns true if the attribute "foo.bar" has been changed since the object "foo" was pulled from the database.

In the past when changing a password there has never been a really simple/elegant way to detect when the password had been changed and only then, hash the password. Now it is trivially simple. Adding the following few lines of code to the model does the job quite nicely.

after_validation :hash_password

def hash_password
if self.password_changed?
self.password = Digest::MD5.hexdigest(self.password)
end
end
Now, whenever the password in the object is modified, whether it is via a form submission or just updating the object in script/console, save the object and the password will be hashed before it is stored. If there are any validations that don't pass the object will not be saved and the password will be the same as it had been.

No comments: