Async authguard in angular 6

扶醉桌前 提交于 2019-11-30 15:49:02

Here is approach for RXJS6, added a variable _isAuthenticated in authentication service to request the server state just when the flag is disabled. I hope that helps others.

Ensure canActivate returns a plain boolean or an observable. The route handler will subscribe to the given observable and reacts to first boolean value coming from the value stream.

auth.guard.ts

import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';

import { Observable } from 'rxjs/';
import { map, finalize } from 'rxjs/operators';
import { DataService } from '../data.service';
import { AuthenticationService } from './authentication.service';

@Injectable()
export class AuthenticationGuard implements CanActivate {

  constructor(private router: Router,
              private dataService: DataService,
              private authenticationService: AuthenticationService) { }

  canActivate(): any {
    const isAuthenticated = this.authenticationService.isAuthenticated();

    // All good
    if ( isAuthenticated ) {
      return true;

    // Hmm, let's verify the user first
    } else {
      return this.authenticationService.isSessionAlive()
        .pipe(
          map(res => {

            // No valid session; let's move to the login page
            if ( res === false ) {
              this.router.navigate(['/login'], { replaceUrl: true });
            }

            return res;
          })
        );
    }
  }

}

auth.service.ts (I'm using rxjs 6)

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { DataService } from '@app/core';

@Injectable()
export class AuthenticationService {

  private _isAuthenticated = false;

  constructor(
    private dataService: DataService
  ) {}

  isAuthenticated(): boolean {
    return this._isAuthenticated;
  }

  isSessionAlive(): Observable<any> {
    return Observable.create((observer) => {
      this.dataService.SessionIsAlive()
        .subscribe((res) => {
          this._isAuthenticated = true;
          observer.next(res.success); // your server response
        }, (err) => {
          this._isAuthenticated = false;
          observer.next(false);
          // observer.error(err); // won't work here you need to use next
        });
    });
  }
}

You might do bit of changes as follows,

Your service,

@Injectable()
export class LoginService {
  public isUserLoggedIn: boolean;
  constructor(
    private router: Router,
    private auth: AuthService) {
    this.isUserLoggedIn = false;
  }

  public loginService(data): void {
    this.auth.isAuthentication(data)
    .subscribe((response) => {
      if (response) {
        this.isUserLoggedIn = true;             
      }else {
        this.router.navigate(['login']);
      }
    });
  }

 public getUserLoggedIn() {
   return this.isUserLoggedIn;
}

and then,

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private login: LoginService) { }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.login.getUserLoggedIn();
  }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!