8

мне интересно, если есть способ вызова метод «забыл пароль» процедуру, не вынуждая мой пользователь выйти изРазрабатывают Забыл пароль для зарегистрированного пользователя

Случая я бег в это: 1. пользователь вступает в систему с facebook, для них создается фальшивый пароль 2. пользователь затем хочет изменить свой адрес электронной почты/имя/пароль или просто использовать не facebook login

поскольку для разработки требуется пароль для изменения этих полей, как он должен, пользователь не в состоянии их изменить

Я думал о том, что просто не forc что пароль не будет установлен, но это не имеет смысла, так что вместо этого я просто показываю поля в виде текста и уведомляю пользователя следовать процедуре «забытый пароль», чтобы установить пароль, а затем они могут изменять поля

вопрос то в том, что я не могу просто ссылку на это из профиля пользователя, так как Разрабатывают сообщит пользователю, что они не могут сделать это в то время уже вошли в систему.

Так есть способ переопределения забыл пароль или/users/password/edit, чтобы зарегистрированный пользователь мог выполнить это действие?

ответ

2

Мое полное решение здесь, потому что я также узнал, что пользователь должен выйти из системы после нажатия ссылки в письме, заключается в добавлении некоторых дополнительных действий UserController для фактического редактирования пароля, а также для его сохранения. Это не идеальное решение, и холод, вероятно, будет сделан лучше, но он работает для меня.

пользовательский контроллер; добавленные методы для сброса

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 

просмотров/разработки/регистрации/редактирования; изменил вид не позволяет пользователю редактировать поля, требующие пароля

<%= 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 %> 

просмотров/изобретают/почтовик/reset_password_instructions; пришлось изменить его, чтобы указать на правый URL в нашем новом случае

<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> 

просмотров/пользователей/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 %> 

конфигурации/routes.rb

get "users/reset_password" 
get "users/reset_password_edit" 

resource :users do 
    post 'do_reset_password' 
end 
4

Вы можете использовать @user.send_reset_password_instructions, чтобы сгенерировать токен сброса пароля и отправить электронное письмо. Если вы просто вызываете почтовый ящик напрямую, токен сброса пароля не будет сгенерирован для аутентификации сброса.

+0

Это было работать намного лучше. – fiestacasey

15

Причина, по которой вы не можете сбросить пароль из-за того, что устройство пытается аутентифицировать пользователя с текущим сеансом, и когда это удается, вы автоматически перенаправляетесь на любой путь, к которому он должен идти. Вам нужно переопределить действие редактирования и обновления контроллера паролей, чтобы пропустить этот шаг.

Вот код. В вашем контроллере паролей добавьте следующие коды (вы можете попросить разработчик создать для вас контроллеры или просто создать следующий контроллер). Переопределение для обновления необходимо, поскольку в противном случае вошедший в систему пользователь будет автоматически выходить после вашего пароля восстановления.(Или, если вы хотите, чтобы это было как, что вы можете избавиться от #update переопределение)

class PasswordsController < Devise::PasswordsController 
    # here we need to skip the automatic authentication based on current session for the following two actions 
    # edit: shows the reset password form. need to skip, otherwise it will go directly to root 
    # update: updates the password, need to skip otherwise it won't even reset if already logged in 
    skip_before_filter :require_no_authentication, :only => [:edit, :update] 

    # we need to override the update, too. 
    # After a password is reset, all outstanding sessions are gone. 
    # When already logged in, sign_in is a no op, so the session will expire, too. 
    # The solution is to logout and then re-login which will make the session right. 
    def update 
    super 
    if resource.errors.empty? 
     sign_out(resource_name) 
     sign_in(resource_name, resource) 
    end 
    end 
end 

Трассы как следующий

# config/routes.rb 
devise_for :users, :controllers => {:passwords => 'passwords'} 
Смежные вопросы