1

我在 Angular 4 和 ASP.Net Core 中开发了一个网站。然而,有一件事一直困扰着我。它有一些使用 JWT 的基本登录实现,我正在使用本地存储来保存用户对象和令牌。

用户登录后一切正常,但每当我刷新浏览器时,Angular 总是要求我再次登录。我在 AppComponent 上有一个方法来刷新令牌并在每次应用程序启动时返回一个新的用户对象(如果它可以重新验证保存在 localStorage 上的令牌,逻辑发生在 asp net core 中)。

无论如何,我一直在四处寻找,我相信我需要返回 Observables。这是另一个具有非常相似问题的线程:

AuthGuard 在检查用户之前不会等待身份验证完成

主要区别在于答案使用火基,我相信他们的对象已经是 Observable 而我的对象是布尔值。

这是我的代码:

存储服务(本地存储)

export class StorageService {

    constructor(private storage: LocalStorageService) { }
    public user: User = null;

    public get isLoggedIn() : boolean {
        return this.user != null;
    }

    public isInRole(roleName: string): boolean {
        if (!this.isLoggedIn)
            return false;

        for (let r of this.user.roles) {
            if (r.name == roleName)
                return true;
        }

        return false;
    }

    public get token(): string {
        return <string>this.storage.get(STORAGE_TOKEN) || null;
    }

    public set token(value: string) {
            if (value == null) {
                this.storage.remove(STORAGE_TOKEN);
            } 
            else {
                this.storage.set(STORAGE_TOKEN, value);
            }
        }    
    }

AuthGuard 实现

export class IsLoggedIn implements CanActivate {

    constructor(private storage: StorageService, private router: Router) { }

    canActivate(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot){

        if (this.storage.isLoggedIn) {
            return true;
        }
        this.router.navigate(['account/login'], {
            queryParams: {
                return: state.url
            }
        });
        return false;
    }
}

AppComponent 上的令牌刷新 (ngOnInit)

     this.net.get<LoginModel>(`Authentication/RefreshToken`).subscribe(t => {
        this.storage.token = t.token;
        this.storage.user = t.user;
     });

最后,这就是我使用 IsInRole 的方式:

export class AdminOnly implements CanActivate {

    constructor(
        private storage: StorageService,
        private router: Router
    ) { }

    canActivate(
        childRoute: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
   ) {
        var message: string = null;

        if (!this.storage.isLoggedIn) {
            message = 'Você precisa se logar!';
        }

        if (!this.storage.isInRole('Admin')) {
            message = 'Você precisa ser um administrador!';
        }

        if (message == null) {
            return true;
        }

        this.router.navigate(['account/login'], {
            queryParams: {
                return: state.url,
                message: message
            }
        });
        return false;
    }
}

我应该如何将我的布尔变量转换为 Observables?欢迎任何其他关于如何解决此问题的意见。提前致谢。

4

1 回答 1

2

您可以将可观察对象上的 .of 用作静态函数每当您订阅时,它将引用当前对象状态。

Rx.Observable.of(state)

这是一个代码笔示例: https ://codepen.io/ndcunningham/pen/OvVxjx ?editors=1111

本地存储服务

    public get isLoggedIn() : Observable<boolean> {
    return Rx.Observable.of(this.user !== null);
}

警卫

export class IsLoggedIn implements CanActivate {

constructor(private storage: StorageService, private router: Router) { }

canActivate(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.storage.isLoggedIn.do(e => !e && this.router.navigate(['account/login'], {
        queryParams: {
            return: state.url
        }
    }));
  }
}
于 2018-03-11T21:25:16.700 回答