[angular] Angular 2-라우팅-Observable로 CanActivate 작업
나는이 AuthGuard 가 구현 (라우팅에 사용) CanActivate을 .
canActivate() {
return this.loginService.isLoggedIn();
}
내 문제는 CanActivate-결과가 HTTP-GET-결과에 달려 있다는합니다 – LoginService를 다시 표시 관찰 가능한 .
isLoggedIn():Observable<boolean> {
return this.http.get(ApiResources.LOGON).map(response => response.ok);
}
그것들을 어떻게 모을 수 있습니까? CanActivate가 백엔드 상태에 의존하도록 만들 수 있습니까?
# # # # # #
편집 :이 질문은 2016 년의 것입니다. 앵귤러 / 라우터의 매우 초기 단계가 사용되었습니다.
# # # # # #
답변
“@ angular / router”를 최신. 예 : “3.0.0-alpha.8”
AuthGuard.ts 수정
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private loginService:LoginService, private router:Router) { }
canActivate(next:ActivatedRouteSnapshot, state:RouterStateSnapshot) {
return this.loginService.isLoggedIn().map(e => {
if (e) {
return true;
}
}).catch(() => {
this.router.navigate(['/login']);
return Observable.of(false);
});
}
}
궁금한 점이 있으면 물어보세요!
답변
각도 5+ 및 RxJS 5.5 Kery 후의 대답 업데이트 연산자는 사용되지 않습니다를. 이제 pipe 및 lettable 연산자 와 함께 catchError 연산자를 사용해야합니다 .catch
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { catchError, map} from 'rxjs/operators';
import { of } from 'rxjs/observable/of';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private loginService: LoginService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.loginService.isLoggedIn().pipe(
map(e => {
if (e) {
return true;
} else {
...
}
}),
catchError((err) => {
this.router.navigate(['/login']);
return of(false);
})
);
}
}
답변
canActivate () 는 Observable<boolean>
반환 된 값으로 받아들 입니다. 경비원은 Observable이 해결하고 값을 볼 때까지 기다릴 것입니다. ‘true’이면 검사를 통과하고, 그렇지 않으면 (다른 데이터 또는 throw 된 오류) 경로를 거부합니다.
당신은 사용할 수 있습니다 .map
를 변환 연산자 Observable<Response>
에 Observable<boolean>
이렇게 같은 :
canActivate(){
return this.http.login().map((res: Response)=>{
if ( res.status === 200 ) return true;
return false;
});
}
답변
나는 이런 식으로 그것을했다 :
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.userService.auth(() => this.router.navigate(['/user/sign-in']));}
보시다시피 http 호출이 실패하면 어떻게 해야할지 userService.auth에 폴백 함수를 보냅니다.
그리고 userService에는 다음이 있습니다.
import 'rxjs/add/observable/of';
auth(fallback): Observable<boolean> {
return this.http.get(environment.API_URL + '/user/profile', { withCredentials: true })
.map(() => true).catch(() => {
fallback();
return Observable.of(false);
});}
답변
이것은 당신을 도울 수 있습니다
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { Select } from '@ngxs/store';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { AuthState } from 'src/app/shared/state';
export const ROLE_SUPER = 'ROLE_SUPER';
@Injectable()
export class AdminGuard implements CanActivate {
@Select(AuthState.userRole)
private userRoles$: Observable<string[]>;
constructor(private router: Router) {}
/**
* @description Checks the user role and navigate based on it
*/
canActivate(): Observable<boolean> {
return this.userRoles$.pipe(
take(1),
map(userRole => {
console.log(userRole);
if (!userRole) {
return false;
}
if (userRole.indexOf(ROLE_SUPER) > -1) {
return true;
} else {
this.router.navigate(['/login']);
}
return false;
})
);
} // canActivate()
} // class
답변
CanActivate는 Observable과 함께 작동하지만 CanActivate : [Guard1, Guard2]와 같이 2 번 호출하면 실패합니다.
여기에서 Guard1에서 False의 Observable을 반환하면 Guard2도 체크인하고 Guard2가 true를 반환하면 경로에 대한 액세스를 허용합니다. 이를 피하기 위해 Guard1은 Observable 대신 boolean을 반환해야합니다.
답변
canActivate ()에서 로컬 부울 속성 (귀하의 경우 기본값은 false)을 반환 할 수 있습니다.
private _canActivate: boolean = false;
canActivate() {
return this._canActivate;
}
그런 다음 LoginService의 결과에서 해당 속성의 값을 수정할 수 있습니다.
//...
this.loginService.login().subscribe(success => this._canActivate = true);