简体   繁体   中英

Angular canActivate Guard with API

I'm currently working on an Angular Webpage, using an python API in the backend. I wanted to add an canActivate Guard, to ensure that the User is in an Adminlist, laying on another Server.

My Problem is, that it seems that the guard doesn't wait for the response of the API, i tested it with a window.alert in the guard itself, and it showed me an "undefined" as Output. When I test my method in my auth.service, I get the correct response in my console.log, so my method seems to return the correct boolean, but my guard seems to not wait for the answer from the API.

I got the following Code:

auth.service.ts:

import { HttpClient} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

import { IAuth } from './IAuth';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

   constructor(private http: HttpClient) { }

Acc: boolean;
getauth(): Observable<IAuth['Access']> {
return this.http.get<IAuth['Access']>('http://x.x.x.x:5555/auth');
}

get Access(): boolean {
   this.getauth().subscribe( data =>
   this.Acc = data);
return this.Acc;
}

}

And this is my auth.guard.ts:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';

import { AuthService} from './auth.service';

@Injectable({
  providedIn: 'root'

})
export class AuthGuard implements CanActivate {
   constructor (
      private auth: AuthService,
      private router: Router
  ) {}
    canActivate(
       next: ActivatedRouteSnapshot,
       state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
          if (!this.auth.Access) {
             this.router.navigate(['/noaccess']);
             window.alert(this.auth.Access);
             window.alert(this.auth.Acc);
           }
          return true;
  }
}

I hope you guys can help me solving this problem, like I said, I get the wrong response in the guard (undefined) for both, accessing the property and accessing the method.

get Access(): boolean {
   this.getauth().subscribe( data => this.Acc = data);
   return this.Acc;
}

you don't wait for your HTTP call to finish, so your guard doesn't waith either. Use this instead.

get Access(): Observable<any> {
   return this.getauth().pipe(tap(data => this.Acc = data));
}

You guard then becomes

canActivate(
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.auth.Access.pipe(map(res => {
      if (!res) { this.router.navigate(['/noaccess']); }
      return !!res;
    }));
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM