4

我有一个运行良好的 Angular 项目,我正在实施 NG-IDLE 和 KeepAlive,以保持会话新鲜并在 API 会话到期之前注销用户。

我的问题是 ng-idle 也在登录页面上运行,这显然不是必需的,因为当它超时时,它会将人带到登录页面。

所以我在我的 app.component.ts 中启动并运行了 ng-idle 和 KeepAlive,但由于我使用的是延迟加载,所以我还有一个 authentication.module.ts 和一个 login.component.ts。

我的根 app.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 {

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

    constructor(private idle: Idle, private keepalive: Keepalive) {

        // 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());

        this.reset();
    }

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

我知道我需要调用 idle.unwatch 以防止空闲运行和 idle.watch 在需要时调用,但是我如何从登录或身份验证模块调用它们,或者我可以从根 app.component 检测。 ts?

毫无疑问,你可以说我是 Angular 的新手,所以如果这是一个菜鸟问题,我深表歉意。

4

4 回答 4

6

由于总是有不止一种方法可以给猫剥皮,这是我自己解决这个问题的方法。我希望其他人将来会发现它有用。

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

import { Location } from '@angular/common';
import { Router } from '@angular/router';

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;
    }
}
于 2018-12-31T15:40:39.000 回答
0

一种方法是为登录以外的路线设置主页。所有 watch 和 un-watch 逻辑都可以从 app.component.ts 移到这里

app.routing.ts

const routes: Routes = [
    { path: 'login', component: LoginComponent },
    {
        path: '', component: HomeComponent,
        children: [
            // add auth requiring routes here
        ]
    }
];

home.component.ts

export class HomeComponent implements OnDestroy {
    constructor() {
        // start watching here
    }  

    ngOnDestroy() {
        // unwatch here
    }
}

home.component.html

<router-outlet></router-outlet>
于 2018-12-31T15:30:44.280 回答
0

user2191410 的好答案,当你把所有路线分开时,停下来很简单。非常感谢,这对我来说是一个指南。

我有这个:

export class InitComponent implements OnInit {

  start watch()

}

ngOnDestroy() {
    // unwatch here
    this.idle.stop();
  }

在我的路由中:

{ path: 'dashboard',
      component: InitComponent,
      canActivate: [ AuthGuard ],
      children: [
          { path: '', component: DashboardComponent }
          All my pages are here...
           ]

}

登录组件来自 InitComponent,如下所示:

const routes: Routes = [
    
  { path: 'login', component: LoginComponent },
  { path: 'lock', component: LockComponent },
  { path: 'recover', component: RecoverComponent }

];

AppComponent 有第一个 router-outlet

<router-outlet></router-outlet>    

最后我的 InitComponents 有第二个路由器插座

<router-outlet></router-outlet>
      
于 2020-09-18T19:29:13.937 回答
0

您可以在启动 ng-idle 之前检查用户是否先登录

  this.currentUser = this.authenticationService.currentUserValue;

  if (this.currentUser) {
    this.ifIsLogged = true ;

    // sets an idle timeout of 5 seconds, for testing purposes.
    idle.setIdle(3000000);
    // sets a timeout period of 5 seconds. after 20 seconds of inactivity, the user will be considered timed out.
    idle.setTimeout(2000000);
    // 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.' ;
      alert('No longer idle. ') ;
    });

    idle.onTimeout.subscribe(() => {
      this.idleState = 'Timed out!';
      this.timedOut = true;
      this.logout() ;
    });
    
    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());
    this.reset();

  }
于 2020-09-26T16:05:38.303 回答