身份验证分解为部分问题,更改密码

时间:2011-05-12 22:06:19

标签: ruby-on-rails authentication

我正在构建一个身份验证,从头开始没有Devise或Authlogic,它将独立保存:user表的三个不同部分。我试图让它保存非必需品,如用户真实姓名和年龄验证,没有密码。如果:user想要更改登录详细信息,例如:loginname:email,则他们需要输入:password才能实现更改。如果:user想要更改其:password,则同样如此。 这是:user表的模型。

class User < ActiveRecord::Base
attr_accessor   :password, :old_password, :current_password
attr_accessible :loginname, :email, :password, :password_confirmation,
                 :name, :title_forName, :age_verify, :old_password, 
                 :current_password

email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
loginname_regex = /\A[\w\d]+\z/i
password_regex = /\A(?=.*[\d])(?=.*[A-Z])([1-zA-Z0-1@*#$.]{6,20})\z/

validates :loginname, :presence     => true,
                      :format       => { :with => loginname_regex },
                      :length       => { :maximum => 30},
                      :uniqueness   => { :case_sensitive => false }
validates :email,     :presence     => true,
                      :format       => { :with => email_regex },
                      :uniqueness   => { :case_sensitive => false }
validates :password,  :presence     => true,
                      :on           => :create, 
                      :on           => :change_password_update,
                      :on           => :change_password,
                      # :on           => :update, #This fixes the problem with the password not being validated, but breaks everything else
                      :confirmation => true,
                      :length       => { :within => 6..20 },
                      :format       => { :with => password_regex }
validates :name,      :length       => { :maximum => 75 }
validates :old_password, :presence  => true,
                         :on        => :change_password_update,
                         :on        => :change_password,
                         :format    => { :with => password_regex }
validates :current_password, :presence  => true,
                         :on        => :change_login_update,
                         :on        => :change_login,
                         :format    => { :with => password_regex }

before_save do
     if ( !self.password.blank? || !self.password_confirmation.blank?) #This will keep from a blank password being saved to an encryption.
        :encrypt_password
    end
end

这是控制器上:user

的更新部分
def update
@user = User.find(params[:id])
if params["change_login_update"]
    change_login_update
else
    if params["change_password_update"]
        change_password_update
    else
        if @user.update_attributes(params[:user])
        flash[:success] = "Profile updated."
        redirect_to @user
        else
        @title = "Edit user"
        render 'edit'
        end
    end
end

这适用于:user登录部分

def change_login_update
    if @user.has_password?(params[:user][:current_password])
        if @user.update_attributes(params[:user])
        flash[:success] = "Login details updated."
        redirect_to @user
        else
        @title = "Change Login Details"
        render 'change_login'
        end
    else
        flash[:notice] = "Password Didn't Match Our Records"
        @title = "Change Login Details"
        render 'change_login'
    end
  end

这适用于:password_change控制器

上的:users部分
def change_password_update
    if @user.has_password?(params[:user][:old_password])
        if @user.update_attributes(params[:user])
        flash[:success] = "Password updated."
        redirect_to @user
        else
        @title = "Change Password"
        render 'change_password'
        end
    else
        flash[:notice] = "Original Password Didn't Match Our Records"
        @title = "Change Password"
        render 'change_password'
    end   
  end

1(更新非重要内容) - 编辑用户主页上的提交按钮,只会更改不影响:user登录的内容,没有事故,需要更改的所有内容都会更新。

2(更新登录详细信息) - 提交按钮名为"change_login_update":flash正常工作,:email和{{1}的字段验证也适用。点击提交后,系统会要求用户输入正确的密码,并在保存数据之前进行密码匹配,但不会检查:loginname的输入数据是否格式正确。这似乎是添加到:current_password模型中的:on字段无法正常运行的问题。

3(更新密码) - 提交按钮名为:user"change_password_update"正常,但:flash:password验证不要开火。密码匹配:password_confirmation也适用。如果这些字段都输入正确,:old_password将触发,但密码不会更新。如果使用:flash[:success],则密码将正确保存,但其他所有内容都将中断,因为:on => update,无法在任何其他页面上进行编辑。

对于正确的部分,:password语句没有正确触发似乎是一个问题。这是我第一次使用:on路径,因此非常感谢任何帮助。提前谢谢。

2 个答案:

答案 0 :(得分:0)

我认为你不能使用:就像那样,你只能使用:on with validates_each,validates_with和唯一的选项是 - &gt; :save,:create,:update

所以你不能只是将一个随机方法传递给:当发生这种情况时会发生事件,它只能在保存,创建和更新时触发(默认为保存)。

您可以在过滤之后或之前执行您正在查看的内容。 使用:

before_create:run_before_create_validations

这将在任何创建之前触发run_before_creation_validations。 我在这里你可以检查它是否是一个change_password_update,并运行一些验证。

答案 1 :(得分:0)

我的解决方案是将:if语句添加到验证

validates :password,  :presence     => true,
                      :on           => :create,
                      :confirmation => true,
                      :length       => { :within => 6..20 },
                      :format       => { :with => password_regex }
validates :name,      :length       => { :maximum => 75 }
validates :old_password, :presence  => true,
                          :format    => { :with => password_regex },
                          :if        => :old_password_check?
validates :current_password, :presence  => true,
                         :if        => :login_check?,
                         :format    => { :with => password_regex }
validates :password,  :presence     => true,
                       :confirmation => true,
                       :length       => { :within => 6..20 },
                       :format       => { :with => password_regex },
                       :if           => :old_password_check?

在此之后所有验证工作正常但密码未正确保存,解决方法是我写错了before_save这是更正的版本

before_save do
     if( !self.password.blank? )
        encrypt_password
    end
end

现在一切都很完美。谢谢大家的帮助