在Angular 2中的dont call request方法中扩展http

时间:2016-11-29 13:14:03

标签: http angular jwt

我是Angular 2的新手,我正在尝试使用JWT创建一个应用程序。因此,要执行此操作,请按照帖子http://www.adonespitogo.com/articles/angular-2-extending-http-provider/

但我是个问题,请求方法永远不会调用,登录后我必须刷新页面才能发送令牌。

这是我的课程

http.service.ts

import { Injectable } from '@angular/core';
import { Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class HttpService extends Http {

  constructor (backend: XHRBackend, options: RequestOptions) {    
    let token = localStorage.getItem('auth_token'); // your custom token getter function here
    options.headers.set('Authorization', `Bearer ${token}`);
    options.headers.append('Content-Type', 'application/json');
    super(backend, options);
  }

  request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    let token = localStorage.getItem('auth_token');
    if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
      if (!options) {
        // let's make option object
        options = {headers: new Headers()};
      }
      options.headers.set('Authorization', `Bearer ${token}`);
      options.headers.append('Content-Type', 'application/json');
    } else {
    // we have to add the token to the url object
      url.headers.set('Authorization', `Bearer ${token}`);
      url.headers.append('Content-Type', 'application/json');
    }
    return super.request(url, options)
                .catch(this.catchAuthError(this));
  }

  private catchAuthError (self: HttpService) {
    // we have to pass HttpService's own instance here as `self`
    return (res: Response) => {
      console.log(res);
      if (res.status === 401 || res.status === 403) {
        // if not authenticated
        console.log(res);
      }
      return Observable.throw(res);
    };
  }
}

app.module.ts

providers: [{
      provide: HttpService,
      useFactory: (backend: XHRBackend, options: RequestOptions) => {
        return new HttpService(backend, options);
      },
      deps: [XHRBackend, RequestOptions]
    }, LoggedInGuard, UserService],

picture.service.ts

@Injectable()
export class PictureService {

    url: string = 'v1/pictures';

    constructor(private http: HttpService) { }

    list(): Observable<PictureComponent[]> {
         return this.http
                    .get(this.url)
                    .map(res => res.json());
    }

}

要使用picture.service.ts的组件

@Component({
    moduleId: module.id,
    selector: 'picture-list',
    templateUrl: './pictureList.component.html'
})
export class ListagemComponent { 

    pictures: PictureComponent[] = [];
    service: PictureService;
    msg: String = '';

    constructor(service: PictureService){
        this.service = service;
        this.service
            .list()
            .subscribe(pictures => {
                this.pictures = pictures;
            }, err => console.log(err));
    }

 }

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

您是否在模块中提供了picture.service?如果没有,您应该在@component或您的模块中提供它,如果您想要全球化的话。

答案 1 :(得分:0)

我扩展了XHRBackend

import { Injectable } from '@angular/core';
import { Request, XHRBackend, BrowserXhr, ResponseOptions, XSRFStrategy, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class ExtendedXHRBackend extends XHRBackend {

  constructor(browserXhr: BrowserXhr, baseResponseOptions: ResponseOptions, xsrfStrategy: XSRFStrategy) {
    super(browserXhr, baseResponseOptions, xsrfStrategy);
  }

  createConnection(request: Request) {
    let token = localStorage.getItem('token');
    request.headers.set('x-access-token', `${token}`); 
    request.headers.set('Content-Type', 'application/json');
    let xhrConnection = super.createConnection(request);
    xhrConnection.response = xhrConnection.response.catch((error: Response) => {
      if (error.status === 401 || error.status === 403) {
        console.log('access not alowed');
        localStorage.removeItem('token');
      }
      return Observable.throw(error);
    });
    return xhrConnection;
  }
}

并在app模块上使用

providers: [{ provide: XHRBackend, useClass: ExtendedXHRBackend }]

在此之后我解决了这个问题并且工作得很好