创建一个Angular用户“安全”服务

时间:2018-07-03 18:06:33

标签: angular

我正在尝试创建一个用于我的Angular应用程序的安全服务,并且遇到了一个问题,它多次调用后端API(由它确定用户拥有的权限),但是我只希望它调用一次,其他所有人都可以支持该请求。

我在UI的许多地方都有类似的东西

<button pButton type="button" class="ui-button-warning" (click)="customPointsDisplay=true" icon="fa fa-plus"
    style="margin-top: 8px" [disabled]="disabled" *ngIf="securityService.isAdmin() | async"></button>

该行的关键点是* ngIf行,它在其中调用组件以检查人员是管理员还是其他安全级别。这是通过异步完成的,因为我希望它们触发调用以加载信息(如果需要)。

然后在安全服务组件中,我有以下代码。

loadSecurity(): Observable<void> {
    if (!this.loading) {
        this.loading = this.http.get(this.baseApiUrl + `loadSecurity`)
            .map((result) => {
                var data = this.extractData(result);
                this.isAdminUser = data.IsAdmin;
                this.isCommercializationTeamUser = data.IsCommercializationTeam;
                this.isRedTeamUser = data.IsRedTeam;
                this.isBlueTeamUser = data.IsBlueTeam;
                this.isVisitorUser = data.IsVisitor;
                this.isProjectOwnerTeamUser = data.IsProjectOwnerTeam;
                this.isProjectTeamUser = data.IsProjectUserTeam;
                this.isSensoryInsightsTeamUser = data.IsSensoryInsightsTeam;
            });
    }

    return this.loading;
}

checkSecurity(whichUser: string): Observable<boolean> {
    return Observable.create((observer: any) => {
        if ((this as any)[whichUser] !== undefined) {
            observer.next((this as any)[whichUser]);
            observer.complete();
        } else {
            this.loadSecurity()
                .subscribe(() => {
                    observer.next((this as any)[whichUser]);
                    observer.complete();
                },
                (error: any) => this.handleError(error));
        }
    });
}

isAdmin(): Observable<boolean> {
    return this.checkSecurity('isAdminUser');
}

在此代码中,您可以看到isAdmin方法,该方法称为checkSecurity方法。在check security方法内部,您可以看到它首先检查组件中的各个属性是否已经存在,如果已经存在,则它直接返回值,否则调用load security方法,该方法发出并请求http。这个http请求实际上是确定用户拥有的安全级别并返回该信息的工作,然后将该信息存储在组件的各个属性中并返回到链中。

我的问题是http调用被无数次地执行,我只希望进行一次http调用,并且我希望收到任何其他请求以使用或等待该请求。

2 个答案:

答案 0 :(得分:0)

它在解决/守卫中被调用吗?为什么不只是添加一个标志,以查看是否选中?

isAdmin(): Observable<boolean> {
    return (isRoleChecked) ? Observable.of(!!role): this.checkSecurity('isAdminUser');
}

答案 1 :(得分:0)

我发现了这一点,我需要的是另一种抽象级别,因此在实际的http.get调用中仅调用了1个订阅。我将loadSecurity方法更改为这样。

 loadSecurity(): Observable<void> {
        this.loadingMain = Observable.create((observer: any) => {
            if (!this.loading) {
                this.loading = this.http.get(this.baseApiUrl + `loadSecurity`)
                    .map((result) => {
                        var data = this.extractData(result);
                        this.isAdminUser = data.IsAdmin;
                        this.isCommercializationTeamUser = data.IsCommercializationTeam;
                        this.isRedTeamUser = data.IsRedTeam;
                        this.isBlueTeamUser = data.IsBlueTeam;
                        this.isVisitorUser = data.IsVisitor;
                        this.isProjectOwnerTeamUser = data.IsProjectOwnerTeam;
                        this.isProjectTeamUser = data.IsProjectUserTeam;
                        this.isSensoryInsightsTeamUser = data.IsSensoryInsightsTeam;
                    });
                this.loading.subscribe(() => { });
            } else {
                observer.next(this.loading);
                observer.complete();
            }
        });

        return this.loadingMain;
    }