Rails 4: Session Expiry?

2020-02-17 06:49发布

I just made the switch from Rails 3.2 to Rails 4. I'm trying to make sure I'm as up-to-speed as possible on security issues, and I'm concerned about sessions right now. It looks like Rails 4 has moved away from supporting really anything EXCEPT cookie-based sessions, but it sounds like it's not possible to prevent cookie-based sessions from living forever. I've been reading several articles, but this one is the most official: http://guides.rubyonrails.org/security.html#session-expiry . Notice how they point out that this is an issue for cookie-based sessions, then they give a fix for it for database-based sessions (which are now deprecated, apparently).

I'm really confused. I want to be able to prevent an attacker from getting a cookie that gives him permanent access to my login-protected site. Obviously I can set :expire_after in initializers/session_store.rb, but unless I'm wrong that simply sets the expiration of the cookie which is client-side and easily altered by an attacker so the session can live forever. Of course I can make things better by forcing SSL, using secure cookies, and forcing HTTP only, but this will never be a complete defence until I can enforce session expiry.

How can I solve this problem when Rails is deprecating the only ways to have server-side sessions?

I know active record sessions has been moved into a gem and is still available, but the fact remains that it has been deprecated. A solution should be possible without introducing more dependencies, or at the very least without using deprecated features.

3条回答
女痞
2楼-- · 2020-02-17 07:09

Rails has "tamper-proof" session cookies. To prevent session hash tampering, a digest is calculated from the session with a server-side secret and inserted into the end of the cookie. Just make sure you have a long secret. If you want to periodically reset all user sessions change your secret.

To answer your question, if you want to add an extra time-out to the session data you could do:

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

Then, when authenticating users, do:

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

Hope that helps.

查看更多
干净又极端
3楼-- · 2020-02-17 07:12

Actually rails inherits from Rack::Session::Cookie. So you can configure expire_after parameter in your session_store.rb.

Sqore::Application.config.session_store(
  :cookie_store,
  key: '_name_session',
  expire_after: 24.hours
)
查看更多
等我变得足够好
4楼-- · 2020-02-17 07:18

add this to your application controller: 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
查看更多
登录 后发表回答