爲用戶使用密碼重置機制。密碼長度驗證觸發,我試圖理解爲什麼。密碼驗證觸發何時不應觸發?
user.rb
class User < ActiveRecord::Base
has_secure_password
validates :password, length: { minimum: 6 }
...
def create_password_reset_token
self.update_attributes!(password_reset_token: SecureRandom.urlsafe_base64, password_reset_sent_at: Time.zone.now)
end
def reset_password(params)
self.update_attributes!(params)
self.update_attributes!(password_reset_token: nil, password_reset_sent_at: nil)
end
end
password_resets_controller.rb
def create
user = User.find_by_email(params[:email])
if user
user.create_password_reset_token
UserMailer.password_reset_email(user).deliver
redirect_to root_url, :notice => "Email sent with password reset instructions!"
else
flash[:error] = "A user with that email address could not be found."
render 'new'
end
end
def edit
@user = User.find_by_password_reset_token(params[:id])
if @user
render 'edit'
else
flash[:error] = "Invalid password reset code."
redirect_to root_url
end
end
def update
@user = User.find_by_password_reset_token(params[:id])
if @user.password_reset_sent_at < 2.hours.ago
flash[:error] = "Password reset has expired."
redirect_to new_password_reset_path
elsif @user.reset_password(user_params)
flash[:success] = "Password has been reset."
redirect_to root_url
else
render 'edit'
end
end
password_resets/new.html.erb:
<%= form_tag password_resets_path, :method => :post do %>
<%= label_tag :email %>
<%= text_field_tag :email, params[:email] %>
<%= submit_tag "Reset Password" %>
<% end %>
個password_resets/edit.html.erb:
<%= form_for @user, :url => password_reset_path(params[:id]) do |f| %>
<h1 class="centertext">Reset Password</h1>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirm password" %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Update password" %>
<% end %>
錯誤是:
Validation failed: Password is too short (minimum is 6 characters)
拋出它是create_password_reset_token
方法內的行:
self.update_attributes!(password_reset_token: SecureRandom.urlsafe_base64, password_reset_sent_at: Time.zone.now)
爲什麼在驗證觸發在這裏?我沒有對密碼本身做任何事情。我只是在用戶記錄中創建一個令牌和一段時間。
將驗證更改爲說on: :create
使其不觸發。問題是用戶可以將密碼重置爲少於六個字符。
澄清
需要明確的是,操作順序是:「我忘記了密碼」
- 用戶點擊一個鏈接說
- 它們被帶到password_reset_controller/new.html.erb。此表格有一個字段:電子郵件地址。他們輸入他們的電子郵件並提交。
- 控制器會檢查該用戶是否存在。如果有,它會告訴模型生成一個password_reset_token。
- 控制器然後命令一個電子郵件發送給包含令牌的URL的用戶。
- 用戶單擊URL。如果令牌有效,它們將被帶到edit.html.erb並且他們輸入他們的新電子郵件和它的確認。
- 控制器調用reset_password方法,該方法實際上會重置用戶的密碼。
當前,在步驟2中,驗證觸發後,他們進入他們的電子郵件,然後單擊提交。
爲什麼你的'new.html.erb'沒有'password field'?如何在沒有密碼字段的情況下重置密碼? 「驗證」在「密碼字段」上被調用。所以驗證是觸發的,因爲沒有「密碼字段」。 – Pavan
我對密碼重置控制器和相應的edit.html.erb有一個編輯方法。我省略了它們,因爲驗證在它到達之前就被觸發了。 –
我添加了它們以最大限度地減少混淆。 –