不活动/空闲后自动注销

Sam*_*Sam 20 authentication ruby-on-rails devise

如何在rails应用程序中设置如果任何用户空闲30分钟或特定时间段,他应该自动退出.可以任何人给出任何解决方案.我正在使用设计进行身份验证.任何帮助表示赞赏.

Ser*_*sev 24

你应该使用Timeoutable模型特征.

Timeoutable负责确定用户会话是否已经过期.当会话在配置的时间之后到期时,将再次要求用户提供凭证,这意味着,他/她将被重定向到登录页面.

选项

Timeoutable将以下选项添加到devise_for:

  • + timeout_in +:没有活动的用户会话超时的间隔.

在您的模型中,您需要

devise :timeoutable
# along with :database_authenticatable, :registerable and other things.
Run Code Online (Sandbox Code Playgroud)

另外,看一下config/initializers/devise.rb,你可以在那里配置超时值.


kal*_*s33 13

我知道这个问题已经得到了解答,但我认为我也会提供我的解决方案,因为在我的情况下,我正在寻找比Devise的超时功能所能提供的功能更多的功能.非常感谢@Sergio Tulentsev在他的回答的评论部分为我提供了有用的解释和想法!

问题

因为Devise在服务器端运行而不是在客户端运行,所以当身份验证令牌超时时,客户端不会知道超时,直到用户执行调用Rails控制器的操作.这意味着在执行调用Rails控制器的操作之前,用户不会在超时时重定向到登录页面.

在我的情况下,这是一个问题,因为我的网页包含用户敏感信息,如果用户忘记注销并且没有在页面上执行任何操作,我不想无限期地显示这些信息.

我安装了gem auto-session-timeout,它将代码添加到客户端,以定期检查身份验证令牌是否已过期.

依赖

它没有在自述文件中说,但自动会话超时需要jquery-periodicalupdater才能工作. 此页面包含以下原因: 自动会话超时periodicalupdater解释

组态

以下是为了使自动会话超时与Devise一起使用而采取的步骤:

  1. 首先,我按照这里的步骤来自定义Devise会话控制器.仅供参考,我的config/routes.rb文件按以下方式设置:

    Myapp::Application.routes.draw do
      devise_for :users, controllers: { sessions: "users/sessions" }
      #other routes
    end
    
    Run Code Online (Sandbox Code Playgroud)
  2. app/controllers/users/sessions_controller.rb中,我有以下代码:

    class Users::SessionsController < Devise::SessionsController
      layout 'login' #specifies that the template app/views/layouts/login.html.erb should be used instead of app/views/layouts/application.html.erb for the login page
    
      #configure auto_session_timeout
      def active
        render_session_status
      end
    
      def timeout
        flash[:notice] = "Your session has timed out."
        redirect_to "/users/sign_in"
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)
  3. app/controllers/application_controller.rb中,我有以下代码:

    class ApplicationController < ActionController::Base
      # Prevent CSRF attacks by raising an exception.
      # For APIs, you may want to use :null_session instead.
      protect_from_forgery with: :exception
      before_action :authenticate_user!
      auto_session_timeout 30.minutes
    
    end
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,我们使用auto_session_timeout将身份验证令牌到期时间设置为30分钟.这取代了Devise超时功能.

  4. 在我的应用程序,我有两个布局模板-一个用于所有,当他们在(登录用户看到网页应用程序/视图/布局/ application.html.erb),和一个只为登录屏幕(应用程序/意见/layouts/login.html.erb).在这两个文件中,我在html <body>元素中添加了以下行:

    <%= auto_session_timeout_js %>
    
    Run Code Online (Sandbox Code Playgroud)

    此代码将生成Javascript,每隔60秒检查一次身份验证令牌的状态(此时间间隔是可配置的).如果令牌已经超时,Javascript代码会调用timeout该方法的应用程序/控制器/用户/ sessions_controller.rb文件.

    请注意,我已将此代码包含在app/views/layouts/login.html.erb页面中.这样做的原因是,如果登录页面上没有活动超过30分钟(或者application_controller.rb文件auto_session_timeout中的任何设置),则身份验证令牌将过期,并且用户将收到无效的身份验证令牌尝试登录时出错.添加代码将导致在身份验证令牌到期时刷新登录,从而防止发生此错误.<%= auto_session_timeout_js %>

  • @dowi, joeyk16 我没有在 Rails 5 中使用过这个 gem/策略。根据我的理解,从 Rails 4 到 Rails 5 有很大的变化,所以这个 gem 在 Rails 5 中不起作用并不让我感到惊讶。我抱歉,由于我对 Rails 5 缺乏经验,我不知道有什么解决方法。 (2认同)

Dee*_*epa 6

使用Devise Gem:

我们可以使用设计宝石的内置功能,但在超时后它不会自动重定向到登录页面,重定向将在我们执行任何操作后完成.

我们可以自动退出:

通过使用gem"auto-session-timeout"

https://github.com/pelargir/auto-session-timeout

使用这个gem的缺点是,如果用户只键入(执行按键事件)直到超时时间,它将自动注销.

我们可以通过使用Javascript来覆盖缺点:

第1步:定义路线

get 'application/session_time'
Run Code Online (Sandbox Code Playgroud)

第2步:JavaScript将包含

$(document).ready(function(){
if($("#user_logged").is(":visible") == true )
{
    $(document).on( "keypress keydown", function () {
        console.log("hello");
        $.ajax({
            type:"GET",
            url:"/application/session_time",
            dataType:"html",
        });
    });
}
});
Run Code Online (Sandbox Code Playgroud)

第3步:应用程序控制器将包含:

@session_time = 5.minute
auto_session_timeout @session_time
def session_time
  @session_time = 5.minute
end
Run Code Online (Sandbox Code Playgroud)

第4步:div找到它是否登录页面

<% if user_signed_in? %>
  <div id="user_logged"></div>
<% end %>
Run Code Online (Sandbox Code Playgroud)

保留空白div是因为我们必须仅在用户登录时加载JavaScript,因此不是查找当前用户是否为零.

我已经完成了空白div,如果用户登录它将可用,因此在JavaScript开始时检查div_id"user_loged"是否存在.