【问题标题】:Angular make canActivateGuard asynchronousAngular 使 canActivateGuard 异步
【发布时间】:2017-09-14 03:15:24
【问题描述】:

我有一个 Web 应用程序,其中有一个 JWT 令牌传递给管理服务。此 JWT 来自查询 URL,因为存在来自另一个应用程序的重定向。服务中的构造函数检查该 URL 并为其设置 token 值(如果存在该参数)。

我面临的问题是 canActivateGuard 过早触发。当这被称为 observable 以获取服务中的 JWT 时尚未解决,因此当警卫被触发时 JWT 总是不存在。

我已经弄清楚,要使这项工作在 AdminService 中 isLoggedIn() 必须成为一个监听 URL 变化的可观察对象,并且守卫中的 canActivate() 必须订阅它,但不能这行得通。

下面的代码是我目前得到的

// Admin Service
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import 'rxjs/Rx';

import {Router, ActivatedRoute, Params} from '@angular/router';

@Injectable()
export class AdminService {

  token: string;

    constructor(private activatedRoute: ActivatedRoute) {

        activatedRoute.queryParams.subscribe(
            (params) => {
                console.log('queryParams', params);
                if(localStorage.getItem('jwt')) {
                    this.token = localStorage.getItem('jwt');
                }
                else if(params['jwt']) {
                    localStorage.setItem('jwt', params['jwt']);
                    this.token = params['jwt'];
                }
            });
    }


    // Check that JWT is in local storage and valid
    isLoggedin() {
        return (localStorage.getItem('jwt') !== null && localStorage.getItem('jwt') !== 'undefined');
    }
}


// Can Activate guard
// Note that this.authService.isLoggedIn() is called before the set JWT in the service is solved

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(
    private authService: AdminService,
    private router: Router
  ) {
  }

    canActivate() {
        if (this.authService.isLoggedin()) {
            console.log('all ok, proceed navigation to routed component')
            return true;
        }
        else {
            // start a new navigation to redirect to login page
            this.router.navigate(['/unauthorized']);
            return false;
        }
    }
}

【问题讨论】:

  • 你试过使用snapshot吗? activatedRoute.snapshot.queryParams.
  • 不知道为什么会改变什么?
  • “我面临的问题是 canActivateGuard 过早触发。当这被称为 observable 以获取服务中的 JWT 时尚未解决”。所以..使用snapshot,您不必订阅即可获得 JWT..

标签: javascript angular rxjs jwt observable


【解决方案1】:

使用ActivatedRouteSnapshotRouterStateSnapshot,您的问题将得到解决,您无需在服务中订阅 JWT。

这是我在 Angular2 应用程序中使用的代码示例。

auth-guard.ts

import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { AuthCookie } from '../shared/services/auth-cookies-handler';

@Injectable()
export default class AuthGuard implements CanActivate {
    constructor(private router: Router, private _authCookie: AuthCookie) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
        if (this._authCookie.getAuth()) {
            return true;
        } 
        else {
            this.router.navigate(['/login']);
            return false;
        }
    }
}

希望这会对你有所帮助。

【讨论】:

    猜你喜欢
    • 2019-03-31
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2020-03-26
    • 2020-11-13
    相关资源
    最近更新 更多