我需要在用户登录后为每个后续请求设置一些授权头。


为特定请求设置头信息,

import {Headers} from 'angular2/http';
var headers = new Headers();
headers.append(headerName, value);

// HTTP POST using these headers
this.http.post(url, data, {
  headers: headers
})
// do something with the response

参考

但是,以这种方式为每个请求手动设置请求头是不可行的。

我如何设置头设置一旦用户登录,也删除注销这些头?


当前回答

在这种情况下,扩展BaseRequestOptions可能会有很大帮助。看看下面的代码:

import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS, Headers, Http, BaseRequestOptions} from 'angular2/http';

import {AppCmp} from './components/app/app';


class MyRequestOptions extends BaseRequestOptions {
  constructor () {
    super();
    this.headers.append('My-Custom-Header','MyCustomHeaderValue');
  }
} 

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  HTTP_PROVIDERS,
  provide(RequestOptions, { useClass: MyRequestOptions })
]);

这应该包括'My-Custom-Header'在每个调用。

更新:

为了能够在任何时候改变头,而不是上面的代码,你也可以使用下面的代码来添加一个新的头:

this.http._defaultOptions.headers.append('Authorization', 'token');

要删除就可以了

this.http._defaultOptions.headers.delete('Authorization');

还有另一个函数,你可以用来设置值:

this.http._defaultOptions.headers.set('Authorization', 'token');

上述解决方案在typescript上下文中仍然不完全有效。_defaultHeaders是受保护的,不应该这样使用。我会推荐上面的解决方案作为快速修复,但从长远来看,更好的方法是编写自己的包装器来处理http调用,它也可以处理身份验证。以auth0为例,它更好、更简洁。

https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts

Update - June 2018 I see a lot of people going for this solution but I would advise otherwise. Appending header globally will send auth token to every api call going out from your app. So the api calls going to third party plugins like intercom or zendesk or any other api will also carry your authorization header. This might result into a big security flaw. So instead, use interceptor globally but check manually if the outgoing call is towards your server's api endpoint or not and then attach auth header.

其他回答

虽然我很晚才回,但也许能帮到别人。当使用@NgModule时,要向所有请求注入头文件,可以这样做:

(我在Angular 2.0.1中进行了测试)

/**
 * Extending BaseRequestOptions to inject common headers to all requests.
 */
class CustomRequestOptions extends BaseRequestOptions {
    constructor() {
        super();
        this.headers.append('Authorization', 'my-token');
        this.headers.append('foo', 'bar');
    }
}

现在在@NgModule中执行以下操作:

@NgModule({
    declarations: [FooComponent],
    imports     : [

        // Angular modules
        BrowserModule,
        HttpModule,         // This is required

        /* other modules */
    ],
    providers   : [
        {provide: LocationStrategy, useClass: HashLocationStrategy},
        // This is the main part. We are telling Angular to provide an instance of
        // CustomRequestOptions whenever someone injects RequestOptions
        {provide: RequestOptions, useClass: CustomRequestOptions}
    ],
    bootstrap   : [AppComponent]
})

虽然我回答这个问题很晚,但如果有人在寻求更简单的解决方案。

我们可以用angular -jwt。angular2-jwt在从Angular 2应用中发起HTTP请求时,会自动将一个JSON Web令牌(JWT)作为授权标头。

我们可以用高级配置选项设置全局标头

export function authHttpServiceFactory(http: Http, options: RequestOptions) {
  return new AuthHttp(new AuthConfig({
    tokenName: 'token',
        tokenGetter: (() => sessionStorage.getItem('token')),
        globalHeaders: [{'Content-Type':'application/json'}],
    }), http, options);
}

发送每个请求令牌

    getThing() {
  let myHeader = new Headers();
  myHeader.append('Content-Type', 'application/json');

  this.authHttp.get('http://example.com/api/thing', { headers: myHeader })
    .subscribe(
      data => this.thing = data,
      err => console.log(error),
      () => console.log('Request Complete')
    );

  // Pass it after the body in a POST request
  this.authHttp.post('http://example.com/api/thing', 'post body', { headers: myHeader })
    .subscribe(
      data => this.thing = data,
      err => console.log(error),
      () => console.log('Request Complete')
    );
}

迟到总比不到好……=)

您可以采用扩展BaseRequestOptions的概念(从这里https://angular.io/docs/ts/latest/guide/server-communication.html#!#override-default-request-options)并“动态”刷新头(不仅仅是在构造函数中)。你可以像这样使用getter/setter重写“headers”属性:

import { Injectable } from '@angular/core';
import { BaseRequestOptions, RequestOptions, Headers } from '@angular/http';

@Injectable()
export class DefaultRequestOptions extends BaseRequestOptions {

    private superHeaders: Headers;

    get headers() {
        // Set the default 'Content-Type' header
        this.superHeaders.set('Content-Type', 'application/json');

        const token = localStorage.getItem('authToken');
        if(token) {
            this.superHeaders.set('Authorization', `Bearer ${token}`);
        } else {
            this.superHeaders.delete('Authorization');
        }
        return this.superHeaders;
    }

    set headers(headers: Headers) {
        this.superHeaders = headers;
    }

    constructor() {
        super();
    }
}

export const requestOptionsProvider = { provide: RequestOptions, useClass: DefaultRequestOptions };

在这种情况下,扩展BaseRequestOptions可能会有很大帮助。看看下面的代码:

import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS, Headers, Http, BaseRequestOptions} from 'angular2/http';

import {AppCmp} from './components/app/app';


class MyRequestOptions extends BaseRequestOptions {
  constructor () {
    super();
    this.headers.append('My-Custom-Header','MyCustomHeaderValue');
  }
} 

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  HTTP_PROVIDERS,
  provide(RequestOptions, { useClass: MyRequestOptions })
]);

这应该包括'My-Custom-Header'在每个调用。

更新:

为了能够在任何时候改变头,而不是上面的代码,你也可以使用下面的代码来添加一个新的头:

this.http._defaultOptions.headers.append('Authorization', 'token');

要删除就可以了

this.http._defaultOptions.headers.delete('Authorization');

还有另一个函数,你可以用来设置值:

this.http._defaultOptions.headers.set('Authorization', 'token');

上述解决方案在typescript上下文中仍然不完全有效。_defaultHeaders是受保护的,不应该这样使用。我会推荐上面的解决方案作为快速修复,但从长远来看,更好的方法是编写自己的包装器来处理http调用,它也可以处理身份验证。以auth0为例,它更好、更简洁。

https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts

Update - June 2018 I see a lot of people going for this solution but I would advise otherwise. Appending header globally will send auth token to every api call going out from your app. So the api calls going to third party plugins like intercom or zendesk or any other api will also carry your authorization header. This might result into a big security flaw. So instead, use interceptor globally but check manually if the outgoing call is towards your server's api endpoint or not and then attach auth header.

您可以使用拦截器,而不是为每个请求一次又一次地设置报头。

每个发出的请求都会经过拦截器,在拦截器中你可以设置你的认证头,然后释放请求。