# Agile Dev w/Rails, pp.128-129 Hashing Passwords

**URL:** <https://www.ruby-forum.com/t/agile-dev-w-rails-pp-128-129-hashing-passwords/48013>\
**Category:** Rails\
**Created:** [November 15, 2005, 11:14pm UTC](https://www.ruby-forum.com/t/agile-dev-w-rails-pp-128-129-hashing-passwords/48013 "2005-11-15T23:14:24Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![epfrederick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/59ef9b/32.png) [@epfrederick](https://www.ruby-forum.com/u/epfrederick)\
**Post date:** [November 15, 2005, 11:14pm UTC](https://www.ruby-forum.com/t/agile-dev-w-rails-pp-128-129-hashing-passwords/48013/1 "2005-11-15T23:14:24Z")

</div>

Demo: In Task F, Iteration F1 (near File 54 marker), in the Rails book  
by D. Thomas.

He suggests handling password hashing by using the AR callbacks.

attr\_accessor :password def before\_create self.hashed\_password = User.hash\_password(self.password) end

Is this simply to illustrate callbacks? Would it not be easier to  
create a virtual accessor:

def password=(plain)  
hashed\_password = User.hash\_password(plain)  
end

I don’t like the idea of that transient plain-text field and extra  
callback methods.

I’m just wondering if I’m missing something about the whole  
form-\>action-\>AR-\>save cycle where this alternate technique would be  
worse than the callback method.

I can answer my own question here in that it would be hard to enforce  
password policies without a transient plain-text version to validate  
against; however, the question remains: what is the best practice?

Thanks

---

<div class="post-metadata">

**Author:** ![epfrederick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/59ef9b/32.png) [@epfrederick](https://www.ruby-forum.com/u/epfrederick)\
**Post date:** [November 16, 2005, 6:43am UTC](https://www.ruby-forum.com/t/agile-dev-w-rails-pp-128-129-hashing-passwords/48013/2 "2005-11-16T06:43:05Z")

</div>

Edward F. \<epfrederick@…\> writes:

> Is this simply to illustrate callbacks? Would it not be easier to  
> create a virtual accessor:  
> …  
> I’m just wondering if I’m missing something about the whole  
> form-\>action-\>AR-\>save cycle where this alternate technique would be  
> worse than the callback method.
> 
> I can answer my own question here in that it would be hard to enforce  
> password policies without a transient plain-text version to validate  
> against; however, the question remains: what is the best practice?

I tried several ways of accomplishing the same goal; after some  
trial-and-error,  
I settled on the “virtual” approach you describe as being the most  
simple to  
understand (and so theoretically the most maintainable). Other than  
complexity,  
I don’t see that one method has any benefit over the other.

As you suggest in your comment about enforcing password policies, you  
have to  
add a little bit more code to make the virtual attribute approach work  
with form  
validation. Here’s what I did (inside my model):

def password=(password)  
@password = password

salt = random\_string(10)  
hash = Digest::SHA1.hexdigest(salt + password)

self.password\_salt = salt  
self.password\_hash = hash  
end

def password  
return @password if @password  
return ‘password’ if not self.password\_hash.blank?  
end

def password\_is?(password)  
return Digest::SHA1.hexdigest(self.password\_salt + password) ==  
self.password\_hash  
end

Basically, my password= is the same as yours, with the addition of doing  
the  
salt stuff and setting an instance variable to the plain-text password.  
The  
instance variable is never saved, so it is indeed “transient”, as you  
suggest,  
but it’s available for the password method to access for purposes of  
form  
validation.

Since we don’t save the plain-text password we have to come up with  
_something_  
to return when the password method is called and the @password instance  
variable  
is no longer available–so I return the string “password”: it will pass  
my field  
validations, so it serves nicely. You could return the password hash,  
but it’s  
longer than the length limit I have on the password field in my  
validations. Set  
up this way I can put all my password rules in the model as field  
validations,  
and everything automagically works just the way you would want it to.

The third method is what I use to actually check whether the password a  
user  
types is correct or not; I decided to encapsulate it in the model so  
none of the  
rest of my code needs to know anything about salts or any other  
implementation  
details.

–Forrest

---

<div class="post-metadata">

**Author:** ![epfrederick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/59ef9b/32.png) [@epfrederick](https://www.ruby-forum.com/u/epfrederick)\
**Post date:** [November 23, 2005, 8:48pm UTC](https://www.ruby-forum.com/t/agile-dev-w-rails-pp-128-129-hashing-passwords/48013/3 "2005-11-23T20:48:39Z")

</div>

On Nov 15, 2005, at 4:11 PM, Edward F. wrote:

> Is this simply to illustrate callbacks? Would it not be easier to  
> create a virtual accessor:

Basically, yes…
