简体   繁体   English

如何在Rails 3中实现“记住我”功能?

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

What are the best practices to implement a "Remember Me" function in Rails 3 application ? 在Rails 3应用程序中实现“记住我”功能的最佳实践是什么?

I store session information (session id + user id) in the database when user logs in, and I don't want to use any plugins at this moment. 我在用户登录时将会话信息(会话ID +用户ID)存储在数据库中,此时我不想使用任何插件。

Any pointers or code samples will be much appreciated. 任何指针或代码示例将非常感激。

You can just set the expiration on a signed cookie to accomplish this. 您只需在已签名的Cookie上设置过期即可完成此操作。 (Signed cookies are tamper-proof just like the Rails-provided session 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 has an episode on achieving this as well as well as a great HOWTO on implementing those features via BDD with RSpec and Capybara . Railscasts一个关于实现这一点的插曲 ,以及通过BDD与RSpec和Capybara实现这些功能的一个伟大的HOWTO。

I store session information (session id + user id) in the database when user logs in 我在用户登录时将会话信息(会话ID +用户ID)存储在数据库中

I believe that's one approach and the casts above does the same with cookies by issuing each User account a unique authentication token. 我相信这是一种方法,通过向每个User帐户发布唯一的身份验证令牌,上面的强制转换与Cookie相同。

Have been reading the Rails tutorial book and it has an implementation for Remember Me 一直在阅读Rails教程书,它有一个Remember Me的实现

You can check for some hints (The implementation may be different from yours) 您可以检查一些提示(实施可能与您的不同)

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

This is how I implemented remember_me (the below snippet is from my example Rails app on authentication ): 这是我实现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

Just an example without salt: 只是一个没有盐的例子:

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