31

我刚刚从 Rails 3.2 切换到 Rails 4。我正在努力确保我在安全问题上尽可能地了解最新情况,并且我现在担心会话。看起来 Rails 4 已经不再支持除了基于 cookie 的会话之外的任何东西,但听起来不可能阻止基于 cookie 的会话永远存在。我一直在阅读几篇文章,但这是最官方的一篇:http: //guides.rubyonrails.org/security.html#session-expiry。请注意他们如何指出这是基于 cookie 的会话的问题,然后他们为基于数据库的会话(显然现在已弃用)提供了修复。

我真的很困惑。我希望能够防止攻击者获得一个 cookie,该 cookie 使他能够永久访问我的受登录保护的站点。显然我可以在 initializers/session_store.rb 中设置:expire_after,但除非我错了,否则我只是设置了客户端的 cookie 的过期时间,并且很容易被攻击者更改,因此会话可以永远存在。当然,我可以通过强制 SSL、使用安全 cookie 和仅强制 HTTP 来使事情变得更好,但是在我可以强制会话到期之前,这永远不会是一个完整的防御措施。

当 Rails 不赞成使用服务器端会话的唯一方法时,我该如何解决这个问题?

我知道活动记录会话已被移动到 gem 中并且仍然可用,但事实仍然是它已被弃用。一个解决方案应该是可能的,而不需要引入更多的依赖项,或者至少不使用不推荐使用的特性。

4

3 回答 3

45

Rails 有“防篡改”会话 cookie。为了防止会话哈希篡改,从会话中计算出一个摘要,其中包含服务器端的秘密,并插入到 cookie 的末尾。只要确保你有一个很长的秘密。如果您想定期重置所有用户会话,请更改您的密码。

要回答您的问题,如果您想为会话数据添加额外的超时,您可以执行以下操作:

session[:user_id] = user.id
session[:expires_at] = Time.current + 24.hours

然后,在对用户进行身份验证时,请执行以下操作:

if session[:expires_at] < Time.current
  # sign out user
end

希望有帮助。

于 2013-08-21T07:25:32.287 回答
41

实际上 rails 继承自Rack::Session::Cookie. 所以你可以expire_after在你的session_store.rb.

Sqore::Application.config.session_store(
  :cookie_store,
  key: '_name_session',
  expire_after: 24.hours
)
于 2015-02-20T11:28:52.470 回答
3

将此添加到您的应用程序控制器:

before_filter :session_expires, :except => [:login, :logout]
before_filter :update_session_time, :except => [:login, :logout]

def session_expires
  @time_left = (session[:expires_at] - Time.now).to_i 
  unless @time_left > 0
    reset_session
    flash[:error] = 'Lorem Ipsum.'
    redirect_to :controller => 'foo', :action => 'bar'
  end
end

def update_session_time
  session[:expires_at] = 60.minutes.from_now
end
于 2017-07-05T10:31:27.890 回答