I create custom XHRBackend class to catch 401 error globally. In AuthService I have 2 methods which use http - login and refreshToken. So i have dependency chain like that: Http -> customXHRBackend -> AuthService -> Http. How can I fix this?
export class CustomXHRBackend extends XHRBackend {
constructor(browserXHR: BrowserXhr,
baseResponseOptions: ResponseOptions,
xsrfStrategy: XSRFStrategy,
private router: Router,
private authService: AuthService) {
super(browserXHR, baseResponseOptions, xsrfStrategy);
}
createConnection(request: Request): XHRConnection {
let connection: XHRConnection = super.createConnection(request);
connection.response = connection.response
.catch(this.handleError.bind(this));
return connection;
}
handleError(error: Response | any) {
console.log('ERROR',error['status']);
if(error['status'] === 401) {
this.authService.logout();
this.router.navigate(['/']);
}
return Observable.throw(error);
}
}
AuthService.ts
@Injectable()
export class AuthService {
private loggedIn: boolean = false;
constructor(private http: Http) {
this.loggedIn = !!localStorage.getItem('authToken');
}
login(email: string, password: string): Observable<Response> {
let headers: Headers = new Headers();
headers.set('Content-Type', 'application/json');
return this.http.post('https://httpbin.org/post',
{
email: email,
password: password
},
{
headers: headers
})
.map((response) => {
let res = response.json();
// if (res['success']) {
if (res) {
localStorage.setItem('authToken', res['token']);
localStorage.setItem('refreshToken', res['refreshToken']);
console.log('logged');
this.loggedIn = true;
}
return response;
}
);
}
logout(): void {
localStorage.removeItem('authToken');
this.loggedIn = false;
console.log('Logged out');
}
isLogged(): boolean {
return this.loggedIn;
}
refreshToken(): Observable<Response> {
let headers: Headers = new Headers();
headers.set('token', localStorage.getItem('token'));
headers.set('refreshToken', localStorage.getItem('refreshToken'));
return this.http.get('https://httpbin.org/get', {
headers: headers
});
}
}
Include CustomXHRBackend in app.module.ts
{
provide: XHRBackend,
useFactory: (browserXHR: BrowserXhr,
baseResponseOptions: ResponseOptions,
xsrfStrategy: XSRFStrategy,
router: Router,
authService: AuthService) => {
return new CustomXHRBackend(browserXHR, baseResponseOptions, xsrfStrategy, router, authService);
},
deps: [BrowserXhr, ResponseOptions, XSRFStrategy, Router, AuthService]
}
How about HTTP Interceptors... There's a blog post here.
If you Google you'll find more...
Here's how you hook one into you App Module
you can clone the request in you interceptor and add X-CustomAuthHeader
into headers etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With