对于新注册和用户配置文件中的更新,has_secure_password会正确检查验证。这包括密码的长度和检查密码确认是否匹配。
如何重置密码? (这曾经起作用,但由于某种原因不再起作用)
但是,密码重置资源似乎没有检查这些验证。在关注通过电子邮件发送的密码重置链接后,我可以填写太短的密码和/或不匹配的密码确认,然后它仍然重定向,就好像重置的密码已保存并显示(闪存? )消息已保存新密码。我甚至可以将确认密码留空。所以它似乎没有检查密码重置的验证。另一方面,即使它生成了一个成功消息,它实际上也没有保存新密码(因为它不应该通过验证,因此它不应该保存)。
当我尝试使用此新注册或更新现有配置文件时,它会生成错误消息,例如Password confirmation doesn't match Password
和Password is too short (minimum is 6 characters)
。
有没有人知道我的代码有什么问题,以致密码重置不起作用?我不知道在哪里寻找原因,因为我希望has_secure_password能够自动管理它。这两个用户模型包括:
attr_accessor :remember_token, :activation_token, :reset_token
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
密码重置编辑视图包括(其他用户类型的第二个视图类似):
<%= form_for(@member, url: password_reset_path(params[:id])) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= hidden_field_tag :email, @member.email %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Update password", class: "btn btn-primary" %>
<% end %>
密码重置控制器是:
class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update]
def new
end
def create
@member = Member.find_by(email: params[:password_reset][:email].downcase)
@organization = Organization.find_by(email: params[:password_reset][:email].downcase)
if @organization
@organization.create_reset_digest
@organization.send_password_reset_email
flash[:info] = "An email is sent to you with password reset instructions"
redirect_to root_url
elsif @member
@member.create_reset_digest
@member.send_password_reset_email
flash[:info] = "An email is sent to you with password reset instructions"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end
def edit
if @organization
render action: "editorg"
elsif @member
render action: "editmem"
else
redirect_to root_url
end
end
def update
if password_blank?
flash.now[:danger] = "Password can't be blank"
if @organization
render 'editorg'
elsif @member
render 'editmem'
else
redirect_to root_url
end
elsif
if @organization
@organization.update_attributes(passreset_params)
log_in("organization", @organization)
flash[:success] = "Your password has been reset."
redirect_to @organization
elsif @member
@member.update_attributes(passreset_params)
log_in("member", @member)
flash[:success] = "Your password has been reset."
redirect_to @member
end
else
redirect_to root_url
end
end
private
def passreset_params
if @organization
params.require(:organization).permit(:password, :password_confirmation)
elsif @member
params.require(:member).permit(:password, :password_confirmation)
end
end
# Returns true if password is blank.
def password_blank?
if @organization
params[:organization][:password].blank?
elsif @member
params[:member][:password].blank?
end
end
# Before filters
def get_user
@member = Member.find_by(email: params[:email])
@organization = Organization.find_by(email: params[:email])
end
# Confirms a valid user.
def valid_user
if @organization
unless (@organization && @organization.activated? && @organization.authenticated?(:reset, params[:id]))
redirect_to root_url
end
elsif @member
unless (@member && @member.activated? && @member.authenticated?(:reset, params[:id]))
redirect_to root_url
end
else
flash[:danger] = "Not a valid user."
redirect_to root_url
end
end
# Checks expiration of reset token.
def check_expiration
if @organization
if @organization.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
elsif @member
if @member.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
end