在Rails 3应用程序中实现“记住我”功能的最佳实践是什么?如何在Rails 3中实现“记住我”功能?
我在用户登录时将会话信息(会话ID +用户ID)存储在数据库中,而此刻我不想使用任何插件。
任何指针或代码示例将不胜感激。
在Rails 3应用程序中实现“记住我”功能的最佳实践是什么?如何在Rails 3中实现“记住我”功能?
我在用户登录时将会话信息(会话ID +用户ID)存储在数据库中,而此刻我不想使用任何插件。
任何指针或代码示例将不胜感激。
已经阅读Rails的教程书,它有一个实现。记住
您可以检查一些提示(实施可能和你的不同)
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#sec:remember_me
只是一个例子无盐:
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
Railscasts有an episode对实现这一目标以及实施这些功能via BDD with RSpec and Capybara的一个很好的HOWTO。
我在数据库中存储会话信息(会话ID +用户ID)时
用户登录我相信这是一种方法和上面的石膏发出每个User
帐户做同样与cookies唯一的验证令牌。
我这是怎么实现的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
您可以只设置期满经签署的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
我很惊讶,这种做法是没有得到更多的关注。我花了很多时间试图以设计的方式来做remember_me标记,而其他人则建议这样做。但相比之下,cookies.signed非常干净简单。 –
将user_id存储在签名的cookie中存在安全问题。 SignedCookieJar只签名cookie的内容,而不是名称。这意味着如果您有签名的cookie first_name和user_id,则某人可以复制cookie first_name的值并将其放入user_id,服务器将接受它。如果您在签名的Cookie中输入的用户数量大于您的风险。 – Kazmin