`
fireflyman
  • 浏览: 113357 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

在acts_as_authenticated里使用密码找回功能

阅读更多
虽然不喜欢这个插件,理由嘛,太老了...但还是要用,过段时间有机会再改吧

具体配置什么之类的,参考前一篇:
用rails实现简单邮件发送测试
http://fireflyman.iteye.com/blog/800955

(1)
ruby script/generate authenticated_mailer user


(2)删除models/user_notifier 里的两个方法:UserNotifier和activation
然后折腾后的代码是这样的--<

class UserNotifier < ActionMailer::Base
	@@session = ActionController::Integration::Session.new
#因为url_for是ActionController类控制器的实例方法,所以不能在邮件发送器中直接调用.
#因此我们创建了一个可以调用url_for的ActionController::Integration::Session对象,  #并赋值给一个类变量,这样就可以在邮件发送器中任意使用url_for 了
	def forgot_password(user)
	  setup_email(user)
	  @subject += "Password reset"
	  @body[:url] = @@session.url_for(:controller => "account",
												 :action => "reset_password",
												 :id => user.pw_reset_code,
												 :only_path => false )
	 end
											 
  protected
  def setup_email(user)
  	@subject = "hello World"
	@sent_on = Time.now
        @body[:user] = user
	@recipients = "#{user.email}"
	@from = 'xxx@163.com'
	@headers = {}
  end
end


(3)在views/user_notifier里创建对应的邮件模板,我的如下==>
Dear:<%= @user.login %>

请点击下面链接地址,以便重设密码:
<%= @url %>


(4)为users表增加pw_reset_code字段,目的是存放一个随机生成的记号,需要把这个记号发给用户.
ruby script/generate migration add_pw_reset_code_to_user


class AddPwResetCodeToUsers < ActiveRecord::Migration
  def self.up
	  add_column :users, :pw_reset_code, :string, :limit => 40
  end

  def self.down
	  remove_column :users, :pw_reset_code
  end
end


(5) 打开你的user.rb,增加下面两个类方法
 def forgot_password
    self.password_forgotten = true
	create_pw_reset_code
  end
  
  def reset_password
    update_attributes(:pw_reset_code => nil )
  end
  
  protected
   
    def create_pw_reset_code
	  self.pw_reset_code = Digest::SHA1.hexdigest("secret-#{Time.now}")
    end


(6)打开models/user_observer
class UserObserver < ActiveRecord::Observer

  def after_save(user)
	    UserNotifier.deliver_forgot_password(user) if user.password_forgotten
  end
  
end


(7)在environment.rb里加入这句==?
config.active_record.observers = [:user_observer]


(8)在account_controller里加入下面两个方法:
def forgot_password
     return unless request.post?
	 if @user = User.find_by_email(params[:email])
	    @user.forgot_password
	    @user.save
	    flash[:notice] = "An email with instructions for resetting your password has been sent to your email address."
	    redirect_back_or_default(:controller => "/account")
	 else
	 	flash.now[:notice] = "Could not find a user with the given email address."
		#render :forgot_password
	 end
  end
   
   def reset_password
     @page_title = "Reset Password"
	 @user = User.find_by_pw_reset_code(params[:id]) rescue nil
	 unless @user
	   render(:text => "Not found",:status => 404)
	   return
      end
       return unless request.post?
	   if @user.update_attributes(params[:user])
	      @user.reset_password
		 flash[:notice] = "Password successfully reset."
		 redirect_back_or_default(:controller => "/account")
	   end


(9)到这一步已经没啥好做了,无非就设计两个页面-->自己慢慢改...
forgot_password.rhtml和reset_password.rhtml

<p>Give you email address and we'll send your instructions on how tou create a new one.</p>

<% form_for :user  do |f| %>
<p><label for="email">Email:</label><br/>
<%= text_field_tag :email %><br />
<%= submit_tag "Submit" %>
<% end %>



<%= error_messages_for :user %>
<% form_for :user do |f|%>
  <p>Password:<br/>
  <%= password_field :user,:password %></p>
  <p>Confirm password:<br/>
  <%= password_field :user,:password_confirmation %></p>
  <p><%= submit_tag "Submit"%></p>
<% end %>


好了,经测试,是可以的..这只是一个笔记记录,用上就用,用不上别骂..
分享到:
评论
1 楼 fireflyman 2011-01-05  
users_controller.rb:要改为-->
def forgot_password
  return unless request.post?
  if @user = User.find_by_email(params[:user][:email])
    @user.forgot_password
    @user.save
    flash[:notice] = "A password reset link has been sent to your email address"
    redirect_back_or_default('/')
  else
    flash[:alert] = "Could not find a user with that email address"
  end
end

def reset_password
  @user = User.find_by_password_reset_code(params[:id])
  return if @user unless params[:user]

  if ((params[:user][:password] && params[:user][:password_confirmation]) &&
      !params[:user][:password_confirmation].blank?)
    @user.reset_password
    @user.save
    flash[:notice] = @user.save ? "Password reset success." : "Password reset failed."
    redirect_back_or_default('/')
  else
    flash[:alert] = "Password mismatch"
  end
end


user.rb:

#重置密码
  def forgot_password
    @forgotten_password = true
    self.make_password_reset_code
  end

  def reset_password
    # First update the password_reset_code before setting the
    # reset_password flag to avoid duplicate email notifications.
    update_attributes(:password_reset_code => nil)
    @reset_password = true
  end

  def recently_forgot_password?
    @forgotten_password
  end

  def recently_reset_password?
    @reset_password
  end

protected
#重置码
  def make_password_reset_code
    self.password_reset_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
  end

相关推荐

Global site tag (gtag.js) - Google Analytics