开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜