Giải pháp hoàn chỉnh của tôi ở đây, vì sau đó tôi cũng biết rằng người dùng sẽ phải đăng xuất sau khi nhấp vào liên kết trong email, thêm một số hành động UserController bổ sung để thực sự chỉnh sửa mật khẩu cũng như lưu mật khẩu. Đây không phải là một giải pháp lý tưởng và lạnh lẽo có thể được thực hiện một cách tốt hơn nhưng nó làm việc cho tôi.
bộ điều khiển người dùng; các phương thức được thêm để thực hiện đặt lại
before_filter :authenticate_user!, :except => [:do_reset_password, :reset_password_edit]
def reset_password
id = params[:id]
if id.nil?
id = current_user.id
end
if (!user_signed_in? || current_user.id.to_s != id.to_s)
flash[:alert] = "You don't have that right."
redirect_to '/home'
return
end
@user = User.find(id)
@user.send_reset_password_instructions
respond_to do |format|
format.html { redirect_to '/users/edit', notice: 'You will receive an email with instructions about how to reset your password in a few minutes.' }
end
end
def do_reset_password
id = params[:id]
if id.nil? && !current_user.nil?
id = current_user.id
end
if id.nil?
@user = User.where(:reset_password_token => params[:user][:reset_password_token]).first
else
@user = User.find(id)
end
if @user.nil? || @user.reset_password_token.to_s != params[:user][:reset_password_token]
flash[:alert] = "Url to reset was incorrect, please resend reset email."
redirect_to '/home'
return
end
# there may be a better way of doing this, devise should be able to give us these messages
if params[:user][:password] != params[:user][:password_confirmation]
flash[:alert] = "Passwords must match."
redirect_to :back
return
end
if @user.reset_password!(params[:user][:password],params[:user][:password_confirmation])
@user.hasSetPassword = true
@user.save
respond_to do |format|
format.html { redirect_to '/home', notice: 'Your password has been changed.' }
end
else
flash[:alert] = "Invalid password, must be at least 6 charactors."
redirect_to :back
end
end
def reset_password_edit
@user = User.where(:reset_password_token => params[:reset_password_token]).first
if @user.nil? || [email protected]_password_period_valid?
flash[:alert] = "Password reset period expired, please resend reset email"
redirect_to "/home"
return
end
end
lượt xem/lập/đăng ký/chỉnh sửa; đã thay đổi chế độ xem để không cho phép người dùng chỉnh sửa các trường yêu cầu mật khẩu
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<% if !resource.hasSetPassword %>
<%= f.label :name %><br />
<p style="line-height:24px;"><b><%= @user.name %></b></p>
<div><%= f.label :email %><br />
<p style="line-height:24px;"><b><%= @user.email %> </b></p>
<p style="position:relative; left:150px; width:420px;">
<i>you cannot change any settings because you have not set a password <br />yet, you can do so by following the </i>
<%= link_to "Forgot your password", "https://stackoverflow.com/users/reset_password" %> <i> procedure</i>
</p>
</div>
<% else %>
<p><%= f.label :name %><br />
<%= f.text_field :name %></p>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %> <br />
<%= f.password_field :password %><i>(leave blank if you don't want to change it)</i></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :current_password %> <br />
<%= f.password_field :current_password %>
<i>(we need your current password to confirm your changes)</i>
</div>
<div><%= f.submit "Update" %></div>
<% end %>
<% end %>
lượt xem/devise/mailer/reset_password_instructions; đã phải thay đổi nó để trỏ đến URL đúng trong trường hợp của chúng tôi mới
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password, and you can do this through the link below.</p>
<% if [email protected] %>
<p><%= link_to 'Change my password', 'http://streetsbehind.me/users/reset_password_edit?reset_password_token='[email protected]_password_token %></p>
<!-- todo: there's probably a better way of doing this than just hardcoding streetsbehind.me -->
<% else %>
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
<% end %>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
views/người dùng/reset_password_edit.erb
<%= form_for(@user, :url => url_for(:action => :do_reset_password) , :html => { :method => :post }) do |f| %>
<%= f.hidden_field :reset_password_token %>
<div><%= f.label :password, "New password" %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Change my password" %></div>
<% end %>
config/routes.rb
get "users/reset_password"
get "users/reset_password_edit"
resource :users do
post 'do_reset_password'
end
Điều đó đã làm việc tốt hơn rất nhiều. – fiestacasey