我真的是个傻瓜。 我编写了一项防护服务,以便只有授权(登录)的用户才能访问特定组件。 我将asp.net用于后端,我在服务器端有一个api返回异步状态的Authorized状态。 问题是,有时在调用canActivate方法后api响应就会到达,因此尽管用户已被授权,但该方法返回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
});
}
答案 0 :(得分:0)
canActivate和Promise中的调用授权api可以从canActivate返回true或false。
答案 1 :(得分:0)
这里的问题是API调用与isSignedIn
变量的评估之间存在竞争条件。我们可以解决这个问题。
如果您查看CanActivate
卫队的docs,您会发现Observable<boolean>
是可能的返回类型之一。因此,删除构造函数中的HTTP
代码,将方法返回类型更改为Observable<boolean>
,而不要像完成那样返回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<boolean>
,我们告诉Angular我们将在某个时候 返回一个布尔值,但是我们只是不确切地知道何时那将会发生。因此,在这种情况下,它将等到解决后再继续。
答案 2 :(得分:-1)
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;
}
}
));
}