如果用户已登录,我会在我的网络服务上检查“CanActivate”。
“CanActivate”返回Observable。唯一的担心是我需要恢复这个布尔值,以便能够调整我的视图,如果用户是否连接而没有重做第二个请求......
canActivate(): Observable<boolean>|boolean {
return this.connected();
}
public connected() : Observable<boolean>{
return this.http.get(this.connectedUrl,{ withCredentials: true })
.map(this.extractBoolean)
.catch(this.handleError);
}
感谢您的帮助
答案 0 :(得分:1)
我遇到了类似的问题,并使用身份验证服务解决了这个问题,我在其中使用了BehaviorSubject来跟踪成员身份验证状态:
public member: Subject<Member> = new Subject<Member>();
private _cachedMember: Member;
private _member$: BehaviorSubject<Member>;
constructor(private _http: Http, private _router: Router) {
}
get member$(): Observable<Member> {
if (!this._cachedMember) {
this.getAuthorizedMember().subscribe();
}
return this._member$.asObservable();
}
private getAuthorizedMember(): Observable<Member> {
// call your auth API and set _cachedMember accordingly:
this._cachedMember = member;
this._member$.next(this._cachedMember);
}
我的auth.guard.ts可以激活实施:
canActivate(): Observable<boolean> | boolean {
return this._authService.member$.map(member => {
if (member) return true;
else {
// Set entry url
var currentUrl: URL = new URL(this._document.location.href);
this._authService.entryUrl = currentUrl.pathname;
this._router.navigate(['/']);
return false;
}
});
}
else语句保存url请求,因此登录后会正确重定向成员。
然后,如果_cachedMember为null,则只需要调用您的身份验证API。记得在注销时将_cachedMember设置为null并通知主题。
logout() {
this._cachedMember = null;
this._member$.next(this._cachedMember );
}
[编辑] 我发现早期解决方案存在问题。将授权机制包装在一个observable中是一个好主意,如果_member $ subject被赋值则执行null检查。如果直接导航到一个守卫的路线,初始状态是有效的!
答案 1 :(得分:1)
如果您想在后端发出请求时保存一些数据以确保用户已连接,而不是在guard
中发出HTTP请求,请创建执行此操作的service
请求(无论如何,这是一个很好的做法,无论你是否想要保存请求,都应该这样做。)
也就是说,在service
,这是一个单身人士,您只需map
您的通话(结果为Observable
)并保存service
中的值即可}。
例如:
@Injectable()
export class SomeService {
private userData: IUserData;
constructor(private http: Http) { }
getUserDataIfConnected() {
this.http.get('http://some-url')
.map((res: Response) => res.json() as IUserData)
.map(userData => this.userData = userData)
}
}
然后在你的警卫中:
canActivate(): Observable<boolean> {
return this.someService.getUserDataIfConnected()
// if there was no error, we don't care about the result, just return true : The user is connected
.mapTo(true)
// if the user wasn't logged, your backend shoud return an HTTP error code in the header
// and angular HTTP service will throw an error
.catch(err => return Observable.of(false))
}
它不必比那更复杂:)