# Hacking on restful\_authentication

**URL:** <https://www.ruby-forum.com/t/hacking-on-restful-authentication/136930>\
**Category:** Rails\
**Created:** [May 7, 2008, 1:25pm UTC](https://www.ruby-forum.com/t/hacking-on-restful-authentication/136930 "2008-05-07T13:25:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![matthew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ed655f/32.png) [@matthew](https://www.ruby-forum.com/u/matthew)\
**Post date:** [May 7, 2008, 1:25pm UTC](https://www.ruby-forum.com/t/hacking-on-restful-authentication/136930/1 "2008-05-07T13:25:13Z")

</div>

I am relatively new to Rails, and I recently installed the  
restful\_authentication plugin to manage authentication and users for a  
site I’m developing. I wanted to change the behaviour of the plugin  
so that it returned meaningful error messages to users when a login  
failed (ie to tell the user whether the login failed because the user  
didn’t exist or because the password didn’t match), but this proved  
surprisingly difficult. The problem is that user authentication is  
done in a class method, which returns nil to indicate that the login  
failed.

def self.authenticate  
u = find\_by\_login(login) # need to get the salt  
u && u.authenticated?(password) ? u : nil  
end

I tried quite a few things, but they were all hampered by the fact  
that (a) the nil value represented both kinds of errors and (b)  
returning nil didn’t allow me to use things like virtual attributes to  
store and indication of the actual problem. It was made more  
difficult by the fact that this authentication happened in the model,  
and therefore I was limited in the way that I could communicate back  
to the controller (eg the model doesn’t have access to the flash or  
the session).

Eventually I decided to use custom exceptions for the two different  
types of errors and have the controller separately rescue these to set  
the flash message to indicate what actually went wrong, as these  
seemed like the way to achieve my aim with minimal disturbance to the  
existing system (there seem to be quite a few places that relied on  
the existing design).

def self.authenticate(login, password)  
u = find\_by\_login(login) # need to get the salt  
raise AuthenticatedSystem::UserNotFoundException if u.nil?  
raise AuthenticatedSystem::InvalidPasswordException unless  
u.authenticated?(password)  
return u  
end

I guess what I’m wondering is what would be the best (ie most Rails-  
like) way to implement this if you were starting from scratch with  
this aim in mind ? Would it be better to move more of the logic into  
the controller by changing the authenticate method to an instance  
method without the find, doing the find in the controller and then  
call authenticate on the returned user model to validate the  
password ? Or is there some other more elegant solution that I’m  
missing ?
