javascript - Angular 2 : AuthGard renders the page before it checks whether SecurityContext is applied or not

标签 javascript angular authentication router

我正在使用 Angular,并尝试在某些路径上应用一些 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'));
  }

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

最佳答案

您遇到的问题是 this._authService.getRoles() 进行异步网络调用。 return !this.error; 在网络调用返回之前被触发,因此 !this.error 不会改变,因此仍然是 true。

要解决此问题,您应该能够返回一个可观察对象,如下所示:

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);
  }
);

关于javascript - Angular 2 : AuthGard renders the page before it checks whether SecurityContext is applied or not,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44648483/

相关文章:

html - Swiper.js 垂直幻灯片无法使用 ngx-swiper-wrapper

asp.net - ASP.net 中的成员(member)系统

node.js - Express res.render 不适用于 Angular 路由

javascript - 如何在 Jquery 中切换动画

javascript - 浏览器视口(viewport)外的模态弹出窗口

Javascript:从对象中查找值

ruby-on-rails - 如何在 Devise 中实现安全的主密码/ super 密码身份验证?

JavaScript:四舍五入 100

angular - Angular 4 的国际化

Angular 2 : Custom material theme in each lazy loaded submodule