【问题标题】:api response arrives after canActivate method is called调用 canActivate 方法后 api 响应到达
【发布时间】:2019-08-16 06:24:18
【问题描述】:

我真的是角的菜鸟。 我编写了一个保护服务,以便只有授权(登录)用户才能访问特定组件。 我使用 asp.net 作为后端,我在服务器端有一个 api 来返回授权状态,方法是异步的。 问题是有时 API 响应在调用 canActivate 方法后到达,因此尽管用户已获得授权,但该方法返回 false。

@Injectable()
export class AuthenticationGuardService implements CanActivate {
  isSignedIn: boolean = false;
  result: Object;
  constructor(private router: Router,private http: HttpClient, @Inject('BASE_URL') private url: string) {
    this.http.get(this.url + 'api/Authentication/UserInfo').subscribe(
      result => {
        if (result != null) {
          this.isSignedIn = true;
        }
      }
    )
  }
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

    if (!this.isSignedIn) {
      this.router.navigate(['sign-in']);
    }
    return this.isSignedIn;
  }
}
        public async Task<IActionResult> UserInfo()
        {
            var user = await userManager.GetUserAsync(HttpContext.User);
            if (user == null)
            {
                return null;
            }
            return Json(new
            {
                email = user.Email,
                name = user.FirstName,
                family = user.LastName
            });
        }

【问题讨论】:

    标签: c# asp.net angular api authorization


    【解决方案1】:

    canActivate调用授权接口,canActivate可以返回返回true或false的Promise。

    【讨论】:

      【解决方案2】:

      这里的问题是 API 调用和isSignedIn 变量的评估之间存在竞争条件。我们可以解决这个问题。

      如果查看CanActivate Guard 的docs,您会发现Observable&lt;boolean&gt; 是可能的返回类型之一。所以删除构造函数中的HTTP代码,将你的方法返回类型更改为Observable&lt;boolean&gt;,而不是像你所做的那样返回isSignedIn变量,执行以下操作:

      如果您的 API 调用直接返回布尔值:

      return this.http.get(this.url + 'api/Authentication/UserInfo');

      如果由于某种原因您的 API 直接返回布尔值:

      return this.http
                 .get(this.url + 'api/Authentication/UserInfo')
                 .pipe(result => !!result);
      

      通过返回 Observable&lt;boolean&gt;,我们告诉 Angular 我们将在某个时候返回一个布尔值,但我们只是不知道确切的时间发生。所以在这种情况下,它会等到它解决后再继续。

      【讨论】:

        【解决方案3】:

        canActivate 接受布尔值或可观察的布尔值,避免订阅 试试这个

        canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean>{
        
        return this.http.get(this.url + 'api/Authentication/UserInfo').pipe(map(
          (result) => {
            if (result != null) {
               return true;
            } else {
                this.router.navigate(['sign-in']);
                return false;
             }
          }
         ));
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-13
          • 1970-01-01
          • 1970-01-01
          • 2018-04-12
          相关资源
          最近更新 更多