首页 文章

会话到期后自动注销用户

提问于
浏览
3

我遇到了一个问题:在会话过期时自动注销用户 . 我试图模仿SugarCRM中的行为,一旦你的会话过期,一个警告告诉你你已经注销,你重定向到登录屏幕重新登录 . This happens with or without user interaction.

到目前为止,在yii2中,用户必须事先执行请求 . 会话可能已过期,但页面将保持不变,直到用户尝试执行新请求 . 在处理此请求时,应用程序可以使用控制器筛选器或 beforeAction() 钩子进行检查 .

我想在会话到期后立即将它们重定向到登录页面 . 我该如何自动完成?

5 回答

  • 0

    以上所有答案都是有效的,除了......你必须以另一种方式实现会话 .

    对服务器的任何调用基本上都会重置正常会话 . 通过检查您仍然登录的每x秒,您将完成它,以便您永远不会登出 . 在每次检查呼叫时,您的会话到期时间将重置 .

    因此,必须结合您将修改会话处理方式的事实 . 您希望在实际的页面导航中重置会话计时器,而不是默认情况下PHP处理它 .

  • 5

    SugarCRM必须定期用一些javascript(ajax请求)检查会话,检查Chrome中DevTool的网络选项卡上的XHR,您将在注销警报之前看到此调用 .

  • 1

    用户组件应如下所示:

    'user' => [
        'identityClass' => 'app\models\User',
        'authTimeout' => 300, 
        'enableAutoLogin' => false, // !important to set this
    ],
    

    如果您还想动态设置authTimeout

    我遇到了同样的问题 . 我想动态设置用户的 authTimeout 我也希望用户在时间到期后自动注销并重定向到登录屏幕(无论是否有用户交互) . 这就是我做到的 . 我已将用户 authTimeout 和会话超时设置为 config/web.php 中的相同值,并且我还注册了一个新的元标记,该标记将在会话到期后5秒刷新页面,因此它将自动重定向到登录屏幕 .

    在config / web.php中:

    'on beforeRequest' => function ($event) {
        $user = Yii::$app->user;
    
        if (!$user->isGuest) {
            if (!empty(Yii::$app->params['settings']['security_timeout'])) {
                $user->authTimeout = intval(Yii::$app->params['settings']['security_timeout']);
                Yii::$app->session->set($user->authTimeoutParam, time() + $user->authTimeout);
                Yii::$app->view->registerMetaTag(['http-equiv' => 'refresh', 'content' => $user->authTimeout + 5]);
            }
        }
    },
    

    当然,如果你不想动态设置 authTimeout ,那就简单多了 .

    如果您不需要动态设置authTimeout

    只需在您的布局中或产品中的任何位置注册元标记,并将刷新时间设置为略高于 authTimeout .

    Yii::$app->view->registerMetaTag(['http-equiv' => 'refresh', 'content' => Yii::$app->user->authTimeout + 5]);
    
  • 0

    这是一个非常简单的示例,说明如何使用JavaScript来定期调用ajax来检查用户是否仍然登录 . 这假设您的后端PHP脚本返回{“loggedin”:true / false}的特定格式,并且您的ajax()函数接受我下面实际使用的三个参数,因此你必须修改语法以使其适合你的需要并适应你实际使用的任何ajax函数的要求(比如jQuery,本机JS,等等)你用)...

    var checkLogin = function() {
        //// presumes that you have some ajax function going
        //// with something like ajax(method,url,callback)
        //// and that it's returning something like {loggedin:true/false}
        ajax("GET", "some-check-login-script.php", function(json) {
            var data = JSON.parse(json);
            if (!data.loggedin) {
                runSomeFunctionToAlertOrRefreshOrWhatever();
                clearInterval(logincheckinterval);
            }
        });
    }
    var logincheckinterval = setInterval(checkLogin, 5000);
    

    您只需要修改语法以匹配您的特定框架对进行该ajax调用的要求,然后相应地修改其余部分以执行您希望它执行的操作(警报,提示,自定义对话框,等等)一旦它捕获'从返回的数据返回false'返回值 .

    希望这很有帮助 .

  • 1

    我之前在Yii2应用程序上执行了相同的任务,这就是我所做的 .

    • 使用js setInterval创建小部件并将其插入主布局中 .
    class UserTimeout extends Widget
    {
        public $checkUrl = ['/index/check-user-timeout'];
        public $redirectUrl = ['/index/login'];
    
     public function run()
    {
        $timeout = \Yii::$app->user->authTimeout * 1000 + 5000; // milliseconds
        $url = Url::to($this->checkUrl);
        $redirect = Url::to($this->redirectUrl);
        $this->view->registerJs("
            function checkUserTimeout() {
                $.post('{$url}', function(data){
                    if(data){
                        document.location = '{$redirect}';
                    }
                });
            }
            setInterval(checkUserTimeout, $timeout);
        ");
    }
     
    
    }
    
    • 关闭用户组件中的autoLogin:
    'components'          => [
        'user'         => [
            'enableAutoLogin' => false,
            'authTimeout'     => 60 * 60,
    

    坦率地说,我使用事件yii \ web \ Application'afterRequest'创建它,因为我需要通过cookie自动启用其他请求 .

    • 制作'index / check-user-timeout'动作:
    public function actionUserTimeout()
    {
            $expire = time() - Yii::$app->session->get('__expire');
            if ($expire >= 0) {
                Yii::$app->session->setFlash('warning', Yii::t('common', 'auth_timeout'));
                return true;
            }
            return false;
    }
    

    在此操作之前避免检查用户身份非常重要(不要在其执行的事前()或相关事件中执行此类操作:“if(Yii :: $ app-> user-> isGuest)”) - 这将刷新会话过期值 .

相关问题