[英]AuthGuard can activate goes to end of function and returns false instead of waiting for subscription to return true
I am making an Angular 4 web app.我正在制作一个 Angular 4 网络应用程序。 I need to protect my routes so I am using
AuthGuard
and CanActivate
to check if the user can access a certain route.我需要保护我的路由,所以我使用
AuthGuard
和CanActivate
来检查用户是否可以访问某个路由。
CanActivate
first checks if the id
is in sessionStorage
else it checks my backend if the user is authorized. CanActivate
首先检查id
是否在sessionStorage
否则它会检查我的后端是否用户被授权。 If I click on a project with an id
already in sessionStorage
and it goes into the checkIfIDInStorage
it works fine, however if it goes into the else and makes a call to my API it goes to the end of the function and returns false before the call returns true If I remove the return false
in canActivate
it still doesn't work.如果我在
sessionStorage
单击一个带有id
的项目,它会进入checkIfIDInStorage
它工作正常,但是如果它进入 else 并调用我的 API,它会转到函数的末尾并在调用之前返回 false返回 true 如果我在canActivate
删除return false
它仍然不起作用。 If I click on the project again after I see that it has returned true it works fine.如果我在看到它返回 true 后再次单击该项目,它可以正常工作。
Console output控制台输出
can activate else
before return false
in subscribe if
true
in store
Guard.ts Guard.ts
canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
{
const id = route.params.id;
if (this.checkIfIDInStorage(id)) {
console.log("checking id");
return true;
}
else {
console.log("in can activate else");
this.API.checkProjectOwnership(id).subscribe((data) =>
{
console.log("in subscribe if");
if (data.type === 'AL') {
console.log("true");
this.storeProjectID(id);
return true;
}
else {
console.log("in subscribe else ");
this.router.navigate(['/dashboard']);
}
});
}
console.log("before return false");
return false;
}
storeProjectID(id: string) {
console.log("in store");
this.session.store('id', id);
return true;
}
getProjectID() {
return this.session.retrieve('id');
}
checkIfIDInStorage(id: string) {
const storedID = this.getProjectID();
return (id === storedID);
}
API.service.ts API.service.ts
checkProjectOwnership(params: URLSearchParams): Observable<any> {
const URL = `${this.API}/projects/ownership?id=${params}`;
return this.auth.refreshToken()
.flatMap(() => this.authHttp.get(URL, this.headers))
.map((response: Response) => response.json())
.share()
.catch(this.handleError);
}
I was able to solve it by returning an observable.我能够通过返回一个 observable 来解决它。
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
{
const id = route.params.id;
return new Observable<boolean>((observer) =>
{
if (this.checkIfIDInStorage(id)) {
observer.next(true);
observer.complete();
}
else {
const params = new URLSearchParams();
params.append('id', id);
this.API.checkProjectOwnership(id).subscribe((data) =>
{
console.log("in subscribe if");
if (data.type === 'AL') {
this.storeProjectID(id);
observer.next(true);
observer.complete();
}
else {
this.router.navigate(['/dashboard']);
observer.next(false);
observer.complete();
return false;
}
});
}
});
}
@Injectable()
export class DrawingBoardGuard implements CanActivate {
constructor( private _http: HttpClient, private _router : Router) {
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
let url : string = 'someUrl';
return new Observable<boolean>((observer:any) => {
this._http.get(url)
.map((result) => {
if(!result.isPermitted){
this.navigateToOtherPage(...);
observer.next(false);
observer.complete();
return false;
}else {
observer.next(true);
observer.complete();
return true;
}
})
.catch(err => {
this.navigateToOtherPage(...);
return Observable.of(false);
});
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.