簡體   English   中英

如何在Rails 3中實現“記住我”功能?

[英]How to implement a “Remember Me” function in Rails 3?

在Rails 3應用程序中實現“記住我”功能的最佳實踐是什么?

我在用戶登錄時將會話信息(會話ID +用戶ID)存儲在數據庫中,此時我不想使用任何插件。

任何指針或代碼示例將非常感激。

您只需在已簽名的Cookie上設置過期即可完成此操作。 (簽名的cookie就像Rails提供的session cookie一樣是防篡改的。)

class SessionsController < ApplicationController

  def create
    ...
    user = User.authenticate(params[:email_address], params[:password])

    if params[:remember_me]
      cookies.signed[:user_id] = { value: user.id, expires: 2.weeks.from_now }
    else
      # expires at the end of the browser session
      cookies.signed[:user_id] = user.id
    end
  end

  def destroy
    cookies.delete :user_id
  end
end 

class ApplicationController < ActionController::Base
  ...
  def current_user
    User.find(cookies.signed[:user_id])
  end     
end

Railscasts一個關於實現這一點的插曲 ,以及通過BDD與RSpec和Capybara實現這些功能的一個偉大的HOWTO。

我在用戶登錄時將會話信息(會話ID +用戶ID)存儲在數據庫中

我相信這是一種方法,通過向每個User帳戶發布唯一的身份驗證令牌,上面的強制轉換與Cookie相同。

一直在閱讀Rails教程書,它有一個Remember Me的實現

您可以檢查一些提示(實施可能與您的不同)

http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#sec:remember_me

這是我實現remember_me的方式(下面的代碼片段來自我的示例Rails應用程序驗證 ):

class SessionsController < ApplicationController
  skip_before_filter :login_required, :only => [:new, :create]

  def new
  end

  def create
    @current_user = User.authenticate(params[:email], params[:password])

    if @current_user
      @current_user.track_on_login(request)

      if params[:remember_me]
        cookies[:remember_token] = { :value => @current_user.remember_token, :expires => 24.weeks.from_now }
      else
        cookies[:remember_token] = @current_user.remember_token
      end

      redirect_to dashboard_url, :notice => "Logged in successfully."
    else
      flash.now[:alert] = "Invalid login or password."
      render 'new'
    end
  end

  def destroy
    current_user.track_on_logout
    current_user.reset_remember_token_and_save  # can't rely on the 'save_current_user_if_dirty' after_filter here

    cookies.delete(:remember_token)
    reset_session

    redirect_to root_url, :notice => "You have been logged out."
  end
end

只是一個沒有鹽的例子:

class ApplicationController < ActionController::Base

  protected

  def signin!(user_id)
    return unless user_id
    @current_user = User.find(user_id)
    self.session_user_id = @current_user.id
    self.permanent_user_id = @current_user.id if session[:accept_remember_me]
  end

  def signout!
    self.session_user_id = nil
    self.permanent_user_id = nil
    session[:accept_remember_me] = nil
    @current_user = nil
  end

  def remember_me
    session[:accept_remember_me] = true
  end

  private

  def permanent_user_id
    cookies.signed[:permanent_user_id]
  end

  def permanent_user_id= value
    cookies.permanent.signed[:permanent_user_id] = value
  end

  def session_user_id
    session[:user_id]
  end

  def session_user_id= value
    session[:user_id] = value
  end

end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM