您如何显示足够聪明的会话超时警告以处理多个打开的浏览器或选项卡

问题描述 投票:17回答:4

我已经使用JavaScript实现了会话超时警告,该警告只是询问用户是否要扩展其会话或注销。问题在于这是针对Intranet门户的,在该门户中,高级用户通常会同时向应用程序打开多个浏览器窗口或选项卡。当前,将提示他们即将从每个浏览器窗口中注销。如何使代码更智能,以检测到他们正在使用另一个浏览器会话进行主动访问?

javascript session session-timeout browser-tab
4个回答
2
投票

您必须使用Ajax在服务器上检查会话状态,并跟踪用户拥有的所有打开的会话/窗口。然后,您将只能通过注销警告来定位可用会话之一。

回复您的评论:

不要使用内置的会话机制,请使用服务器端持久性数组或数据库日志自行设计。

[不,HTTP请求中没有任何内容告诉您打开了多少个浏览器,但是当用户打开每个浏览器窗口时,您可以分配自己的sessionID cookie。对服务器进行Ajax调用,查看用户是否超时,并且如果您是会话日志中最低(或最后)的条目,则您是获得警告的浏览器。


2
投票

您不能指望所有选项卡/窗口都属于同一会话,因为它们可以生成并包含在单独的进程中,并且您对此没有太多控制权。

但是,如果您的代码引用了Javascript Cookie,则可以通过回发(同步或异步AJAX)检查伪会话状态。但是,那取决于您在用户浏览器中启用了cookie。


0
投票

这项工作吗?

存储Javascript Cookie并检查以确定是否在另一个选项卡中扩展了会话?

看起来确实可行...


0
投票

安装@ ng-idle@ ng-idle可通过NPM获得。通过运行安装它:

npm install --save @ng-idle/core @ng-idle/keepalive angular2-moment

设置您的应用程序模块打开src / app / app.module.ts并使用

导入Ng2IdleModule
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { NgIdleKeepaliveModule } from '@ng-idle/keepalive'; // this includes the core NgIdleModule but includes keepalive providers for easy wireup

import { MomentModule } from 'angular2-moment'; // optional, provides moment-style pipes for date formatting

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    MomentModule,
    NgIdleKeepaliveModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

然后位于component.ts中

import { Component } from '@angular/core';

import {Idle, DEFAULT_INTERRUPTSOURCES} from '@ng-idle/core';
import {Keepalive} from '@ng-idle/keepalive';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

    currentPath: String;

    idleState = 'Not started.';
    timedOut = false;
    lastPing?: Date = null;

    constructor(private idle: Idle, private keepalive: Keepalive, location: Location, router: Router) {

        // sets an idle timeout of 5 seconds, for testing purposes.
        idle.setIdle(5);

        // sets a timeout period of 5 seconds. after 10 seconds of inactivity, the user will be considered timed out.
        idle.setTimeout(5);

        // sets the default interrupts, in this case, things like clicks, scrolls, touches to the document
        idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);

        idle.onIdleEnd.subscribe(() => this.idleState = 'No longer idle.');

        idle.onTimeout.subscribe(() => {
            this.idleState = 'Timed out!';
            this.timedOut = true;
        });

        idle.onIdleStart.subscribe(() => this.idleState = 'You\'ve gone idle!');
        idle.onTimeoutWarning.subscribe((countdown) => this.idleState = 'You will time out in ' + countdown + ' seconds!');

        // Sets the ping interval to 15 seconds
        keepalive.interval(15);

        keepalive.onPing.subscribe(() => this.lastPing = new Date());

        // Lets check the path everytime the route changes, stop or start the idle check as appropriate.
        router.events.subscribe((val) => {

            this.currentPath = location.path();
            if(this.currentPath.search(/authentication\/login/gi) == -1)
                idle.watch();
            else
                idle.stop();

        });
    }

    reset() {
        this.idle.watch();
        this.idleState = 'Started.';
        this.timedOut = false;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.