import { Injectable } from '@angular/core';
import { Http, ConnectionBackend, Headers, RequestOptions, Request, Response, RequestOptionsArgs } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class SecureHttpService extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
// return super.request(url, options);
return super.request(url, options).catch(this.catchErrors());
}
private catchErrors() {
return (res: Response) => {
if (res.status === 401 || res.status === 403) {
//nav.push(loginPage); I want to do something like this if status is 401
debugger;
}
return Observable.throw(res);
};
}
我正在尝试在401错误状态时导航到登录页面,但由于ionic不允许在服务中使用服务。如何实现这一目标?
app.module.ts: -
providers: [
{
provide: Http,
useFactory: (backend:XHRBackend, defaultOptions:RequestOptions) => {
return new SecureHttpService(backend, defaultOptions);
},
deps: [XHRBackend, RequestOptions]
},
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
答案 0 :(得分:1)
在app.component.ts
或您的第一页中:
import { NavController, Events } from 'ionic-angular';
constructor(navCtrl: NavController, events: Events) {
this.events.subscribe('http:forbidden', error => {
this.navCtrl.push(LoginPage, {errorMessage: error});
});
}
现在您可以从服务中发出:
import { Injectable } from '@angular/core';
import { Http, ConnectionBackend, Headers, RequestOptions, Request, Response, RequestOptionsArgs } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Events } from 'ionic-angular';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class SecureHttpService extends Http {
constructor(public events: Events, backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
// return super.request(url, options);
return super.request(url, options).catch(this.catchErrors());
}
private catchErrors() {
return (res: Response) => {
if (res.status === 401 || res.status === 403) {
// will trigger the event defined earlier which did have access to the NavController
this.events.publish('http:forbidden', "Something went wrong.");
debugger;
}
return Observable.throw(res);
};
}
答案 1 :(得分:0)
@Ukkarsh Prakash我有同样的问题,我使用拦截器将我的oAuth令牌推送到每个http请求的auth头。然后,我想使用相同的拦截器来检测来自我的api的响应401,然后显示我的登录页面。由于我在上面没有看到任何拦截器(如在var newAsset = getFactory().newResource(org.biznet,'ourAsset',assetID);
中),让我发布我的代码:
implements HttpInterceptor
@ Ivaro18上面详述的重要部分是(在我的情况下)401上的事件的提升。然后在我的HomePage等效词中添加了以下内容:
@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {
constructor(private tokenStorage: TokenStorage, private events: Events) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.tokenStorage.getTokenObservable().mergeMap((token: Token) => {
// add the Bearer token to the header
if (token != null) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token.access_token}`
}
});
}
return next.handle(request).do((event: HttpEvent<any>) => {
// do something with the response if you want to
}, (err: any) => {
// we are interested on error
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
this.events.publish('http:forbidden', "Session Expired");
}
}
});
});
}
}
然后当任何http调用返回401时,我的应用程序显示登录页面