Reputation: 41
So I'm working on authenticating with Microsoft AD using adal.js and angular 2. I've got the hang of adal.js and can login, refresh tokens, logout, get users, etc etc.
My problem right now has to deal with extending Http and creating a custom class that on a 401 will retry the request that just failed.
Here is basically what I have right now:
export class HttpInterceptor extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router, private adal: IgAdal) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return this.intercept(super.request(url, this.getRequestOptionArgs(options)));
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.intercept(super.get(url, this.getRequestOptionArgs(options)));
}
intercept(observable: Observable<Response>): Observable<Response> {
return observable.catch((err, source) => {
if (err.status == 401) {
this.adal.acquireTokenObservable().flatMap(data=>{
// NOT SURE WHAT TO DO HERE...
return Observable.throw(err);
})
} else {
return Observable.throw(err);
}
});
}
}
This works great when its not a 401, throws the error like it should. Now when I try to call super.get() after a 401 and a new token has been acquired... It doesn't try the request again, instead I get an error like so...
Cannot read property 'subscribe' of undefined
^^^ I think this has something to do with the subscription to request after all has been returned.
I think it's also worth pointing out that I have the main.ts setup just fine as the interceptors are at least working.
intercept(observable: Observable<Response>): Observable<Response> {
return observable.catch((err, source) => {
if (err.status == 401) {
return this.adal.acquireTokenObservable().flatMap(data=>{
return observable.retry(3);
})
} else {
return Observable.throw(err);
}
});
}
Just tried the "retry" rxjs operator.. seems to be doing what I'd like it to do. Now my question is... How do I send someone to the login page after the retry fails?
This is my first stackoverflow question so I appologize if its not the best layout
Thank you!!
Upvotes: 3
Views: 2422
Reputation: 41
For anyone looking into this... I ending up doing this.
intercept(observable: Observable<Response>): any {
return observable.catch((err, source) => {
if (err.status == 401) {
return this.adal.acquireTokenObservable().flatMap(data=>{
if (data === 'User login is required') {
this.adal.login();
}
return observable;
})
} else {
return Observable.throw(err);
}
});
}
Returning the observable stream itself instead of .retry() seems to do the exact same thing and also just retrys 1 time. Otherwise .retry(1) will actually throw 3 seperate errors for some reason.
The
this.adal.acquireTokenObservable()
Is an observable I did using the adal.js library to return a stream with the new token. Still working on a couple other issues regarding retrying certain requests, but this is a good start.
Upvotes: 1
Reputation: 145
Upvotes: 0