回答

0

只是一个例子无盐:

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 
3

Railscastsan episode对实现这一目标以及实施这些功能via BDD with RSpec and Capybara的一个很好的HOWTO。

我在数据库中存储会话信息(会话ID +用户ID)时

用户登录我相信这是一种方法和上面的石膏发出每个User帐户做同样与cookies唯一的验证令牌。

1

我这是怎么实现的remember_me(下面的代码片段是从我example Rails app on authentication):

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 
7

您可以只设置期满经签署的cookie来实现这一目标。 (签名饼干就像Rails的提供session饼干防篡改的。)

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

我很惊讶,这种做法是没有得到更多的关注。我花了很多时间试图以设计的方式来做remember_me标记,而其他人则建议这样做。但相比之下,cookies.signed非常干净简单。 –

+0

将user_id存储在签名的cookie中存在安全问题。 SignedCookieJar只签名cookie的内容,而不是名称。这意味着如果您有签名的cookie first_name和user_id,则某人可以复制cookie first_name的值并将其放入user_id,服务器将接受它。如果您在签名的Cookie中输入的用户数量大于您的风险。 – Kazmin