Angular 2:AuthGard在检查是否应用SecurityContext之前呈现页面

时间:2017-06-20 09:01:02

标签: javascript angular authentication router

我正在使用角色,我试图在某些路径上应用一些AuthGard。

问题是 canActivate()在用SecurityContext检查之前呈现内容,在验证未应用SecurityContext之后再应用重定向到默认页面(登录)页面。

这是代码的一部分。

app.routing.ts

    {
      path: 'admin',
      canActivate: [AuthGard],
      component: HomeComponent,
      children : [
        {
          path: 'add-merchant-admin',
          component : AddMerchantAdminComponent,
        },
        {
          path: 'list-merchant-admin',
          component : ListMerchantAdminComponent,
        }
      ]
    },

AuthGard.ts

  canActivate(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    this._authService.getRoles().subscribe(
      res => {
        if (res.status == 200) {
          this.roles = JSON.parse(res.text());
          this.role = this.roles[0].authority;
          localStorage.setItem('role', this.role);
          if (this.role == 'ROLE_ADMIN') {
            this._router.navigate(['admin']);
          } else {
            if (this.role == 'ROLE_ANONYMOUS') {
              this._router.navigate(['login']);
              this.error = false;
            }
          }
        } else {
          this._router.navigate(['login']);
          this.error = true;
        }
      }, err => {
        this._router.navigate(['login']);
        this.error = true;
      }
    );
    return !this.error;
  };

AuthService

  getRoles() {
    let headers = new Headers({'Content-Type': 'application/json'});
    let options = new RequestOptions({headers: headers, withCredentials: true});
    return this.http.get('http://10.0.0.239:8080/**/**/RolesResource/getRole', options)
      .map((res) => res)
      .catch((error: any) => Observable.throw(error.text() || 'Server error'));
  }

正确注入所有服务, 通常,在使用 getRole()方法进行验证后,应该应用重定向到保护区域或默认页面。

4 个答案:

答案 0 :(得分:1)

这样的事情应该有效

canActivate(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this._authService.getRoles()
        .map(response => JSON.parse(response.text())[0].authority)
        .do(role => localStorage.setItem('role', role))
        .map( role => role === 'ROLE_ADMIN')
        .catch(() => this._router.navigate(['login']));
};

答案 1 :(得分:1)

您遇到的问题是return !this.error;进行异步的网络调用。在返回网络调用之前,!this.error被触发,因此return this._authService.getRoles().map( res => { if (res.status == 200) { this.roles = JSON.parse(res.text()); this.role = this.roles[0].authority; localStorage.setItem('role', this.role); if (this.role == 'ROLE_ADMIN') { this._router.navigate(['admin']); } else { if (this.role == 'ROLE_ANONYMOUS') { this._router.navigate(['login']); return false; } } } else { this._router.navigate(['login']); return true; } }).catch((err) => { this._router.navigate(['login']); return Observable.of(false); } ); 不会发生变化,因此仍然是真的。

要解决此问题,您应该能够返回一个observable,如下所示:

{{1}}

答案 2 :(得分:0)

而不是返回始终为真的return !this.error;,尝试返回

 canActivate(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        return this._authService.getRoles().map(
          res => {
            if (res.status == 200) {
              this.roles = JSON.parse(res.text());
              this.role = this.roles[0].authority;
              localStorage.setItem('role', this.role);
              if (this.role == 'ROLE_ADMIN') {
                this._router.navigate(['admin']);
              } else {
                if (this.role == 'ROLE_ANONYMOUS') {
                  this._router.navigate(['login']);
                 return false;
                }
              }
            } else {
              this._router.navigate(['login']);
             return true;
            }
          }, err => {
            this._router.navigate(['login']);
            return Observable.of(false);
          }
        );
      };

被修改

答案 3 :(得分:0)

您可以尝试使用return observable,可以更新为true或false。