我遵循Michael Hartl的教程,然后跟随Ryan Bates的Railcast添加重置密码(#274)。也许“试图遵循”更准确,因为尽管经过了数小时的努力/搜索/ tial&错误,我仍然无法获得重置密码。
不得不偏离Ryan的调用:@ user.update_attributes(params [:user]):@ user.update_attributes(user_params),因为我收到了ForbiddenAttributesError。
我还必须在User类中注释#validates:password,length:{minimum:6},因为它在提交时失败(即使提交的密码长度大于6)。
代码目前不会产生任何错误,redirect_to root_url,:notice => “密码已被重置!”作品。但是,密码不会在db中更新。
非常感谢任何见解。
应用程序/模型/ user.rb
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
has_secure_password
#validates :password, length: { minimum: 6 }
before_create :create_remember_token
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.digest(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64(40)
end while User.exists?(column => self[column])
end
def create_remember_token
self.remember_token = User.digest(User.new_remember_token)
end
end
应用程序/控制器/ users_controller.rb
class UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update]
before_action :correct_user, only: [:edit, :update]
def index
@users = User.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params) if @user.save
sign_in @user
flash[:success] = "Welcome!"
redirect_to @user
else
render 'new'
end
end
def edit
end
def update
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :password_reset_token)
end
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
end
应用程序/控制器/ password_resets_controller.rb
class PasswordResetsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
user.send_password_reset if user
redirect_to root_url, :notice => "Email sent with password reset instructions."
end
def edit
@user = User.find_by_password_reset_token!(params[:id])
end
def update
@user = User.find_by_password_reset_token!(params[:id])
if @user.password_reset_sent_at < 2.hours.ago
redirect_to new_password_reset_path, :alert => "Password reset has expired."
elsif @user.update_attributes(user_params)
redirect_to root_url, :notice => "Password has been reset!"
else
render :edit
end
end
private
def user_params
params.require(:user).permit(:id, :name, :email, :created_at, :updated_at, :password_digest, :remember_token, :admin, :auth_token, :password_reset_token, :password_reset_sent_at)
end
end
应用程序/视图/ password_resets / edit.html.erb
<%= form_for @user, :url => password_reset_path(params[:id]) do |f| %>
<% if @user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in @user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
<div class="actions"><%= f.submit "Update Password" %></div>
<% end %>
应用程序/视图/ password_resets / new.html.erb
<h1>PasswordReset#new</h1>
<%= form_tag password_resets_path, :method => :post do %>
<div class="field">
<%= label_tag :email %>
<%= text_field_tag :email, params[:email] %>
</div>
<div class="actions"><%= submit_tag "Reset Password" %></div>
<% end %>
password_resets没有型号。
答案 0 :(得分:0)
在 app / views / password_resets / edit.html.erb 中,您的表单会说明:password
和:password_confirmation
。但是,在PasswordResetsController中,使用描述:id, :name, :email, :created_at, :updated_at, :password_digest, :remember_token, :admin, :auth_token, :password_reset_token, :password_reset_sent_at
的user_params进行更新。请注意缺少您尝试设置的属性。在控制台中,您可能会看到一条消息,指示已丢弃所需的属性。您添加到user_params的许多属性在任何上下文中都没有意义,因为用户在任何情况下都不会设置它们,例如:id, :created_at, :updated_at, :password_digest, :remember_token, :admin, :auth_token, :password_reset_token, :password_reset_sent_at
。事实上,这些可能是明显的安全风险(您是否希望用户决定他们是否是管理员?)。如果您将PasswordResetsController中的user_params方法更改为以下内容,您可能会有更好的运气:
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
有意义吗?