Session Timeout in angular 4 using ng-idle

2019-08-29 09:16发布

问题:

I have referred code from https://hackedbychinese.github.io/ng2-idle/ and modified it as , during onTimeoutWarning a modal popup will be opened and on timeout session will be cleared and navigated to Login page.

It is working fine. However, after navigating to Login page if user is logging in again, then timeout functionality is not working.

Component

import { Component, ViewChild } from '@angular/core';
import 'rxjs/add/operator/map';
import { SessionService } from '../Service/session.service';
import { LoginService } from '../Service/login.service';
import { Router } from '@angular/router';
import { DatePipe } from '@angular/common';
import { Idle, DEFAULT_INTERRUPTSOURCES } from '@ng-idle/core';
import { Keepalive } from '@ng-idle/keepalive';
import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
import { Subject } from 'rxjs';
@Component({
    selector: 'app-header',
    templateUrl: 'app/HTML/header.html'
})

export class HeaderComponent {


    //TodayDate: string;
    public EmployeeDetail: string = "";
    IsLoggedOut: boolean = true;

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

    public flag: boolean = false;
    public sessionWarningTimer$ = new Subject();
    TodayDate: string;
    public CurrentDate: Date = new Date();
    @ViewChild('modal') modal: ModalComponent;


    constructor(
        private _loginservice: LoginService,
        private _sessionService: SessionService,
        private router: Router,
        public datePipe: DatePipe,
        private idle: Idle,
        private keepalive: Keepalive,) {

        _loginservice.getLoggedInName.subscribe(name => this.changeName(name));

        if (_sessionService.getItem("CurrentUser") != null) {
            this.TodayDate = this.datePipe.transform(Date.now(), 'MM/dd/yyyy');
            _loginservice.set(this._sessionService.getItem("CurrentUser").LastName + " " + this._sessionService.getItem("CurrentUser").FirstName + " | " + "Emp No - " + this._sessionService.getItem("CurrentUser").EmployeeNumber + " | " + "Dept - " + this._sessionService.getItem("CurrentUser").CurrentEmployee.DepartmentId + " | " + this._sessionService.getItem("CurrentUser").CurrentEmployee.FullTime + " | " + this._sessionService.getItem("CurrentUser").CurrentEmployee.Exempt  );

        }

        /**************************************************************************************************/
        this.reset();
        // sets an idle timeout of 5 seconds, for testing purposes.
        idle.setIdle(50);
        // sets a timeout period of 5 seconds. after 10 seconds of inactivity, the user will be considered timed out.
        idle.setTimeout(50);
        // 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;
            //Logout

            this._loginservice.set("");
            this._sessionService.setItem("IsLoggedOut", true);
            this._sessionService.removeItem("CurrentUser");
            this.flag = false;
            this.timedOut = false;
            this.idleState = '';
            this.router.navigate(['Login']);
            this.modal.dismiss();
        });
        idle.onIdleStart.subscribe(() => this.idleState = 'You\'ve gone idle!');
        idle.onTimeoutWarning.subscribe((countdown) => {
            this.idleState = 'Your session is about to expire and you will logged out in ' + countdown + ' seconds!';
            if (!this.flag) {
                this.modal.open();
                this.flag = true;
            }
        });

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

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

        this.reset();
        /**************************************************************************************************/
    }
    private changeName(name: string): void {
        this.EmployeeDetail = name;
    }


    Logout() {
        this._loginservice.set("");
        this._sessionService.setItem("IsLoggedOut", this.IsLoggedOut);
        this._sessionService.removeItem("CurrentUser");
        this.router.navigate(['Login']);
    }

    reset() {
        this.idle.watch();
        this.idleState = 'Started.';
        this.timedOut = false;

    }
}

HTML

<modal-header [show-close]="true">
    <h3 class="pageTitle">
        Session Timeout
    </h3>
</modal-header>
<modal-body>

    <section>
        <p><strong>{{idleState}}</strong></p>
        <!--<p *ngIf="lastPing"><small>Last keepalive ping <strong>{{lastPing | date:'h:mm a z'}} TimeAgo</strong></small></p>
        <button (click)="reset()" *ngIf="timedOut">Continue Session</button>-->
    </section>



</modal-body>
<modal-footer>
    <div *ngIf="!timedOut">
        <a class="btn btn-default" (click)="modal.dismiss()">Continue Session</a>
    </div>
</modal-footer>

回答1:

You should change your onTimeout subscribe like this. It worked with me.

 this.idle.onTimeout.subscribe(() => {
          //console.log('timeout')
          this.idleState = 'Timed out!';
          this.timedOut = true;
          swal.close();
          this.idle.stop();
          //prevent init multiple time
          this.idle.onTimeout.observers.length = 0;
          this.idle.onIdleStart.observers.length = 0;
          this.idle.onIdleEnd.observers.length = 0;

          this.signOut(this.getPath().substring(1));
});