web-dev-qa-db-ja.com

Angular 2分後の自動ログアウト

(Angular2で)機能を実装したい。つまり、ログイン後、ユーザーがブラウザーを30分間アイドル状態にしていた場合、30分後に戻ったときにログアウトする必要があります。これは、フロントエンドのみで行う必要があります。

angular CLI of Angular version 2.4を使用しています。

Angular2アプリケーションにこの機能を実装するにはどうすればよいですか?

6
Er Vipin Sharma
import { Injectable } from "@angular/core";
import { Router } from '@angular/router'
const MINUTES_UNITL_AUTO_LOGOUT = 60 // in mins
const CHECK_INTERVAL = 15000 // in ms
const STORE_KEY =  'lastAction';
@Injectable()
export class AutoLogoutService {
 public getLastAction() {
    return parseInt(localStorage.getItem(STORE_KEY));
  }
 public setLastAction(lastAction: number) {
    localStorage.setItem(STORE_KEY, lastAction.toString());
  }

  constructor(private router: Router) {
    this.check();
    this.initListener();
    this.initInterval();
    localStorage.setItem(STORE_KEY,Date.now().toString());
  }

  initListener() {
    document.body.addEventListener('click', () => this.reset());
    document.body.addEventListener('mouseover',()=> this.reset());
    document.body.addEventListener('mouseout',() => this.reset());
    document.body.addEventListener('keydown',() => this.reset());
    document.body.addEventListener('keyup',() => this.reset());
    document.body.addEventListener('keypress',() => this.reset());
  }

  reset() {
    this.setLastAction(Date.now());
  }

  initInterval() {
    setInterval(() => {
      this.check();
    }, CHECK_INTERVAL);
  }

  check() {
    const now = Date.now();
    const timeleft = this.getLastAction() + MINUTES_UNITL_AUTO_LOGOUT * 60 * 1000;
    const diff = timeleft - now;
    const isTimeout = diff < 0;

    if (isTimeout)  {
      localStorage.clear();
      this.router.navigate(['./login']);
    }
  }
}

私は同様のことをする必要があり、これを作成しました: https://github.com/harunurhan/idlejs

これは特にangular用ではありませんが、TypeScriptで書かれているため、公式のタイピングを取得できます。

シンプルで構成可能で、依存関係はありません。いくつかの例:

import { Idle } from 'idlejs/dist';

// with predefined events on `document`
const idle = new Idle()
  .whenNotInteractive()
  .within(60)
  .do(() => console.log('IDLE'))
  .start();

カスタムイベントターゲットとイベントを使用することもできます。

const idle = new Idle()
  .whenNot([{
    events: ['click', 'hover'],
    target: buttonEl,
  },
  {
    events: ['click', 'input'],
    target: inputEl,
  },
  ])
  .within(10)
  .do(() => called = true)
  .start();
5
harunurhan

基本的にあなたがしなければならないことは、何らかのクライアント活動の場合にフラグを設定することであり、30分後にそのフラグをチェックしなければなりません。フラグが設定されていない場合は、ユーザーがアクティブではなかったので、logout()アクションを実行できます。

以下は、便利なコードサンプルです( ngrx を使用)。

_export class ClientActiveService {
  constructor(
    private store: Store<fromRoot.State>,
  ) { }

  run() {
    window.onload = () => { this.setActive(); };
    window.onmousemove = () => { this.setActive(); };
    window.onmousedown = () => { this.setActive(); }; 
    window.onclick = () => { this.setActive(); };
    window.onscroll = () => { this.setActive(); }; 
    window.onkeypress = () => { this.setActive(); };
  }

  setActive() {
     this.store.select(fromRoot.getClientActive)
     .take(1)
     .subscribe((active) => {
        if (!active) {
          this.store.dispatch(new layout.ClientActiveAction());
        }
      });
  }
}
_

ClientActiveServiceは、クライアントがアクティブな場合にアクションを実行するだけのサービスです。 _app.component.ts_のような場所で、そのサービスを注入してthis.clientActiveService.run();を呼び出す必要があります

次に、コードのどこかに、ClientInactiveActionアクションをサブスクライブする30分のタイマーを設定する必要があります

_    setInterval(() => {
      this.store.select(fromRoot.getClientActive)
      .take(1)
      .subscribe((active) => {
        if (!active) {
          this.auth.logout();
        }
      });
    }, 30 * 60 * 1000);
_

ngrx を使用していない場合は、ClientActiveServiceサービスに_variable/flag_を設定するだけで済みます。次に、setTimeout()でその変数を確認し、logout()アクションを実行します

それ以外の場合は、 ng2-idle ライブラリを使用する必要があります。その場合 Angular 2-ng2-idleを使用したログアウト が役立つ可能性があります。

2
kuncevic.dev