在控制器级别处理空白参数的Rails

时间:2012-10-25 04:58:42

标签: ruby-on-rails

我有一个用户模型:

class User < ActiveRecord::Base
  has_secure_password
  # validation lets users update accounts without entering password
  validates :password, presence: { on: :create }, allow_blank: { on: :update }
  validates :password_confirmation, presence: { if: :password_digest_changed? }
end

我还有 password_reset_controller

def update
  # this is emailed to the user by the create action - not shown
  @user=User.find_by_password_reset_token!(params[:id])

  if @user.update_attributes(params[:user])
    # user is signed in if password and confirmation pass validations
    sign_in @user
    redirect_to root_url, :notice => "Password has been reset."
  else
    flash.now[:error] = "Something went wrong, please try again."
    render :edit
  end
end

你能在这里看到问题吗?用户可以提交空白密码/确认,并且rails将对其进行签名,因为用户模型允许更新时为空白。

这不是一个安全问题,因为攻击者仍然需要访问用户的电子邮件帐户才能接近此操作,但我的问题是提交6个空白字符的用户将被登录,并且他们的密码将会不要为他们改变,这可能会导致后来的混乱。

所以,我提出了以下解决方案,在推进生产之前,我想检查是否有更好的方法:

def update
  @user=User.find_by_password_reset_token!(params[:id])

  # if user submits blank password, add an error, and render edit action     
  if params[:user][:password].blank?
    @user.errors.add(:password_digest, "can't be blank.")
    render :edit
  elsif @user.update_attributes(params[:user])
    sign_in @user
    redirect_to root_url, :notice => "Password has been reset."
  else
    flash.now[:error] = "Something went wrong, please try again."
    render :edit
  end
end

我应该检查nil还是空白?是否有任何轨道模式或惯用的红宝石技术来解决这个问题?

[Fwiw,我在html输入上有required: true,但是也想要这个处理过的服务器端。]

1 个答案:

答案 0 :(得分:0)

请试试这个:

我们可以使用 - 目前?

例如:

if !params[:user][:password].present?