如何使用Devise为Rails应用设置10小时强制会话过期(非Timeoutable)
实现Devise强制会话10小时过期(无论活跃状态)
1. 为用户模型添加会话过期字段
首先给User模型添加存储会话过期时间的字段:
rails generate migration AddSessionExpiresAtToUsers session_expires_at:datetime rails db:migrate
2. 登录时初始化会话过期时间
新建或修改app/controllers/users/sessions_controller.rb(继承Devise的会话控制器),重写create方法,登录成功后设置10小时后的过期时间:
class Users::SessionsController < Devise::SessionsController def create super current_user.update(session_expires_at: 10.hours.from_now) if current_user end end
在config/routes.rb中指定自定义会话控制器:
devise_for :users, controllers: { sessions: 'users/sessions' }
3. 添加全局会话过期检查
在app/controllers/application_controller.rb中添加前置过滤器,每次请求时检查会话是否已过期:
class ApplicationController < ActionController::Base before_action :check_session_expiry private def check_session_expiry return unless current_user&.session_expires_at.present? if current_user.session_expires_at < Time.current sign_out current_user redirect_to new_user_session_path, alert: '您的会话已过期,请重新登录' end end end
4. 与Timeoutable模块共存的说明
如果同时启用了Devise的Timeoutable模块,两个逻辑会独立生效:
- Timeoutable负责非活跃超时(如30分钟无操作登出)
- 自定义逻辑负责绝对会话时长(10小时强制登出)
哪个条件先满足就触发对应的登出操作。
5. 可选:登出时清空过期标记
可在会话控制器的destroy方法中清空过期时间字段(非必须操作):
def destroy current_user.update(session_expires_at: nil) if current_user super end
内容的提问来源于stack exchange,提问作者guy
相关产品推荐
相关产品推荐

