User Authentication: Providing separate errors for invalid email/password entry
In my Rails app I'm trying to produce a separate flash.now[:alert]
for invalid :email
and :password
, respectively. So if a user enters the correct email but wrong password, the :alert
warns the user of an invalid password and vice versa. Here's what I开发者_开发技巧 have in my SessionsController:
def create
if user = User.authenticate(params[:email], params[:password])
session[:user_id] = user.id
redirect_to user.profile, :notice => "Logged in successfully"
elsif user.email != params[:email]
session[:email] = @user.email
flash.now[:alert] = "Invalid email. Try again!"
render :action => 'new'
else
session[:password] = @user.password
flash.now[:alert] = "Invalid password. Try again!"
render :action => 'new'
end
end
Rendering this gives me an undefined method for email. Can anyone help me figure out what I'm doing wrong?
DISCLAIMER: Obviously this is a really bad idea as an attacker could keep on trying emails until he found one that did match and then he could start trying passwords for this email he knows exists at your database, but you're asking, so it's up to you deciding to do this or not.
Your authenticate method obviously only returns the user if the email and password did match, change your authenticate method to return a boolean and a user if there is any available. It would look somewhat like this:
def authenticate(email, password)
u = first(:conditions => {:email => email, :state => 'active'})
u && u.authenticated?(password) ? [true, u] : [false, u]
end
Then, at your controller:
def create
result , user = User.authenticate(params[:email], params[:password])
if result
session[:user_id] = user.id
redirect_to user.profile, :notice => "Logged in successfully"
elsif user
session[:email] = @user.email
flash.now[:alert] = "Invalid email. Try again!"
render :action => 'new'
else
session[:password] = @user.password
flash.now[:alert] = "Invalid password. Try again!"
render :action => 'new'
end
end
And this should work.
精彩评论