Сброс пароля, когда пользователь настроил иметь hashed_password - PullRequest
0 голосов
/ 29 февраля 2012

В моем приложении на Rails я настроил в своей таблице пользователей строку для :email и :hashed_password.Однако я хочу предоставить возможность сброса пароля.После Railscast 274 у меня все настроено, но реальный пароль не меняется на тот, который я сбросил как.Я подумал, что, возможно, мне придется изменить :password на :hashed_password в моей модели User, где я обрабатываю проверки, но :password работает в других местах, поэтому я исключил это.Может кто-нибудь помочь мне разобраться?

Вот моя User модель:

class User < ActiveRecord::Base
  attr_accessor :password
  attr_accessible :email, :password, :password_confirmation    

  before_save :encrypt_new_password
  before_create { generate_token(:auth_token) }
  before_validation :downcase_email

  has_one :profile, :dependent => :destroy

  accepts_nested_attributes_for :profile

  validates :email, :uniqueness => true,
                :length => { :within => 5..50 },
                :format => { :with => /^[^@][\w.-]+@[\w.-]+[.][a-z]{2,4}$/i }
  validates :password, :confirmation => true,
                   :length => { :within => 4..20 },
                   :presence => true,
                   :if => :password_required?

  def self.authenticate(email, password)
    user = find_by_email(email)
    return user if user && user.authenticated?(password)
  end

  def authenticated?(password)
    self.hashed_password == encrypt(password)
  end

  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 generate_token(column)
    begin
      self[column] = SecureRandom.hex
    end while User.exists?(column => self[column])
  end
end

Моя password_resets_controller:

class PasswordResetsController < ApplicationController
  layout "password_reset"

  def new
  end

  def create
    user = User.find_by_email(params[:email])
    if user
      user.send_password_reset
      redirect_to new_password_reset_path, :notice => "Check your email for password reset instructions."
    else
      redirect_to new_password_reset_path, :notice => "Sorry, we couldn't find that email. Please try again."
    end

  end

  def edit
    @user = User.find_by_password_reset_token!(params[:id])
    session[:user_id] = @user.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 => "Your password reset link has expired."
    elsif @user.update_attributes(params[:user])
      redirect_to profile_path(@user), :notice => "Great news: Your password has been reset."
    else
      render :edit
    end
  end
end

Мой код формы сброса пароля:

<%= form_for @user, :url => password_reset_path(params[:id]) do |f| %>
  <% if @user.errors.any? %>
  <div id="error_messages">
    <% for message in @user.errors.full_messages %>
    <li class="error"><%= message %></li>
    <% end %>
  </div>
  <% end %>

  <p class="label"><label for="password">New Password:</label></p>
  <p><%= password_field_tag :password, nil, :autofocus => true, :autocomplete => 'off', :placeholder => 'Enter a new password' %></p>
  <p class="label"><label for="password_confirmation">Confirm Password:</label></p>
  <p><%= password_field_tag :password_confirmation, nil, :autofocus => false, :autocomplete => 'off', :placeholder => 'Reenter your new password' %></p>

  <%= submit_tag 'Update Password', :class => 'button orange' %>

<% end %>

Мое users_controller действие обновления:

def update
  @user = current_user
  if @user.update_attributes(params[:user])
    redirect_to settings_path, :notice => 'Updated user information successfully.'
  else
    render :action => 'edit'
  end
end

Сообщение моего сервера при обновлении пароля:

Started POST "/password_resets/56be9c1168637d64eaa42b2551ef9b6c" for 127.0.0.1 at Thu Mar 08 19:36:03 -0500 2012
  Processing by PasswordResetsController#update as HTML
  Parameters: {"commit"=>"Update Password", "password_confirmation"=>"[FILTERED]", "authenticity_token"=>"N8v69nP9NbaGVGdYwmv6EF8uIp4/Vqld/y+Q2K40CMQ=", "utf8"=>"\342\234\223", "id"=>"56be9c1168637d64eaa42b2551ef9b6c", "password"=>"[FILTERED]"}

Ответы [ 2 ]

2 голосов
/ 10 марта 2012

Похоже, потому что вы используете password_field_tag, параметры игнорируются при обновлении пользовательской модели. Попробуйте вместо этого использовать f.password_field, чтобы параметры пароля были вложены в params[:user].

Кроме того, вы также можете вызвать if @user.update_attributes(:password => params[:password], :password_confirmation => params[:password_confirmation]) в PasswordResetsController.

1 голос
/ 14 марта 2012

Не забудьте изменить submit_tag на f.submit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...