首页 文章

Angular 4 Guard订阅

提问于
浏览
0

我的方案使我在路由激活时验证/登录Windows用户 . 所以我只是验证用户是否已经过验证,如果没有,我会调用服务器来生成令牌并期望返回true给canActivate()可能它没有按预期工作 .

一段代码:

auth.guard.ts

import { Observable } from 'rxjs/Observable';
import { CanActivate, Router, ActivatedRouteSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
import { AuthService } from './../data/auth.service';
import { TokenService } from '../auth/token.service';
import { of } from 'rxjs/observable/of';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(
        private loginService: AuthService,
        private tokenService: TokenService,
        private router: Router) {        
    }

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
        const operation = route.data.operation;

        if (!this.tokenService.isAuthenticated() && !this.login()) {            
            console.log('canActive1: ', false);
            return of(false);
        }

        console.log('canActive: ', true);
        return of(true);
    }    

    login() {
        this.loginService.getToken().subscribe((user) => {
            console.log('token returned..');
            if (user && user.token) {
                this.tokenService.storeToken(user.token);
                return true;
            }
            return false;
        });
    }
}

Console:

  • canActivate1:false

  • 令牌已返回..

3 回答

  • 1

    您没有返回 login() 方法的结果 . 试试这个 .

    login(): Observable<boolean> {
        return this.loginService.getToken().subscribe((user) => {
            console.log('token returned..');
            if (user && user.token) {
                this.tokenService.storeToken(user.token);
                return true;
            }
            return false;
        });
    }
    
  • 1

    这是异步的,因此控制台日志会在稍后出现 . 除此之外,您的问题是您尝试从订阅返回数据,这是不可能的 . 你需要返回一个Observable .

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
        const operation = route.data.operation;
    
        return this.login().map(bool => {
          if(!bool && !this.tokenService.isAuthenticated()) {
            return false;
          }
          return true;
          }
        })
    }    
    
    login() {
      // use map instead!
      return this.loginService.getToken().map((user) => {
        console.log('token returned..');
        if (user && user.token) {
          this.tokenService.storeToken(user.token);
          return true;
        }
        return false;
      });
    }
    
  • 0

    首先,您必须使用 login() : Observable<boolean 返回login()函数的结果,正如其他人正确提到的那样 .

    其次,我能理解的问题是这条线: -
    if (!this.tokenService.isAuthenticated() && !this.login()) .

    我想当你调用tokenService.isAuthenticated()时,你必须检查用户是否有令牌,对吧?

    所以,如果一个人没有获得一个令牌,那么 this.tokenService.isAuthenticated() 将返回false,这也是你的 if (!this.tokenService.isAuthenticated() && !this.login()) 也将返回错误,因为你已经应用了AND条件 .

    调用login()函数将设置令牌,但在此之前,您的tokenServiceisAuthenticated()函数将返回false并且路由不会被激活

相关问题