Angular会话超时和管理

44

有没有办法使用Angularjs管理用户会话? 我的意思是:

  • 当系统处于空闲状态时,会话超时。
  • 在会话即将过期时发出警报,并提供恢复会话的选项。
  • 如果会话已过期,则在尝试进行请求时重定向(或执行任何其他操作)。

拦截器是否是解决此问题的好选择? 您能提供一个例子吗?


@georgeawg 这个问题比被引用的那个问题更早,因此必须是重复的。 - Osy
3个回答

58

尝试使用 ng-idle。它是一个简单的组件,你可以在那里设置超时和警告时间,在达到超时之前。然后你可以查询服务器以进行用户注销或类似操作。

myApp.config(function(IdleProvider, KeepaliveProvider) {
  IdleProvider.idle(900); // 15 min
  IdleProvider.timeout(60);
  KeepaliveProvider.interval(600); // heartbeat every 10 min
  KeepaliveProvider.http('/api/heartbeat'); // URL that makes sure session is alive
});

myApp.run(function($rootScope, Idle) {
  Idle.watch();
  $rootScope.$on('IdleStart', function() { /* Display modal warning or sth */ });
  $rootScope.$on('IdleTimeout', function() { /* Logout user */ });
});

在上述配置中,当用户空闲超过900秒(不移动鼠标、按任何键或按钮等)时,会显示警告。然后等待60秒并注销用户(向服务器发送请求,可能销毁服务器会话)。

为了确保服务器会话不会过期(即使用户正在移动鼠标),Keepalive服务将每10分钟向服务器发送一次请求。这个时间必须小于服务器会话过期时间。

查看演示


2
编辑后在run()函数中添加对Idle.watch()的调用,否则计时器不会启动,空闲事件也不会触发。如果您能给出一个好的解释并使用当前的语法,我会给您加1分。 - Boris
@Boris,谢谢你。你的编辑已被拒绝,所以我已经自己添加了它。 - fracz
感谢添加编辑功能。你有什么想法,为什么它被拒绝了?我肯定没有使用 watch() 是无法使其正常工作的,而且其他人似乎也遇到了这个问题。 - Boris
3
决定接受或拒绝编辑的用户通常对所涉及的技术/问题不熟悉。因此,他们经常以“试图回答”的理由拒绝修改源代码的编辑。在这种情况下,最好为原帖留下评论,说明回答/问题需要改进。 - fracz

5

4
请不要只回答链接。 - Yatrix

1

我已经使用ng-idle一段时间了,用于以下需求。

我们的要求是当用户闲置60分钟时。在55分钟后,弹出确认框,询问您是否要继续会话(我使用了sweet alert)。如果用户点击继续,则重置空闲时间,否则通过调用广播方法强制注销。

必须在app.config中的用户登录时进行配置,如下所示。

app.config(['KeepaliveProvider', 'IdleProvider', function (KeepaliveProvider, IdleProvider) {
IdleProvider.idle(TimeOut.firstAPiCall);--It will call Idle On method
IdleProvider.timeout(TimeOut.SessionTimeOut);--It will be called when the total time is (TimeOut.firstAPiCall +TimeOut.SessionTimeOut)
KeepaliveProvider.interval(TimeOut.interval);}]) --It will be called like a heart beat for mentioned timeout until the idle start has not occured.

以下是显示弹出窗口的代码:
   $scope.$on('IdleStart', function () {   
    $scope.$broadcast('SessionIdleUpdate', 'IdleStart', TimeOut.FirstApicall);
    $rootScope.idleTimerSession = setTimeout(function () {
        console.log("pop up appeared on : " + new Date())
        $scope.timedout = SweetAlert.swal({
            title: "Alert",
            text: "Your session is about to expire in 5 minutes, Do you want to continue?",
            type: "warning",
            showCancelButton: true,
            confirmButtonColor: "#DDDDD",
            confirmButtonText: "CONTINUE",
            cancelButtonText: "No"
        }, function (isConfirm) {
            if (isConfirm) {
                clearTimeout(idleTimer);
            }
            else {
                console.log("pop up closed from confirm on  : " + new Date())
                $scope.$broadcast('SessionTimeOutLogOut', null);
                Idle.unwatch();
                $scope.started = false;
            }
        });

        //This check is to handle idle pop up if it appears and user doesnt perform any action it will simply logout.
        var idleTimer = setTimeout(function () {

            swal.close();            
            $scope.$broadcast('SessionTimeOutLogOut', null);
            Idle.unwatch();
            $scope.timedout = null;
        }, (TimeOut.sessionTimeOut) * 1000);
    }, (TimeOut.idleTimeOut - TimeOut.idleCheckDuration) * 1000);-- Time out is added to hold the pop up for that much duration . Because once the idle start is occured you wont be able to call the API 

});

以下是处理空闲结束事件的代码:
  $scope.$on('IdleEnd', function () {
        $scope.$broadcast('SessionIdleUpdate', 'IdleEnd', 0));    
    clearTimeout($rootScope.idleTimerSession);
    closeModals();
});

以下是“超时”的代码,它将在--(TimeOut.firstAPiCall + TimeOut.SessionTimeOut)之后调用。
  $scope.$on('IdleTimeout', function (forceLogout) {


        swal.close();
        $scope.$broadcast('SessionTimeOutLogOut', null);
        Idle.unwatch();

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接