我需要将Authorization标头附加到我的Angular2应用程序完成的每个HTTP请求中。
第一个请求是登录请求,它没有授权标头。登录成功后,将从服务器返回一个令牌,我需要将其作为授权头附加到每个后续HTTP请求中。
我从服务器获取令牌没有任何问题。我可以使用angular2应用程序成功登录。但问题是,令牌未附加到后续请求标头。
这是我的实施。
我创建了一个扩展BaseRequestOptions类的CustomRequestOptions类。
@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
constructor(private _globals: Globals) {
super();
this.headers.append('Content-Type', 'application/json');
}
addHeader(headerName: string, headerValue: string) {
console.log("Custom req options, setting the customer header "+headerName+" , "+headerValue);
this.headers.append(headerName, headerValue);
}
}
我已将其添加到@NgModule
,以使此CustomRequestOptions
为全局。(在所有组件中可见)
@NgModule({
imports: [ BrowserModule, HttpModule, routing, FormsModule ],
declarations: [ AppComponent, TendersComponent, TenderCategoriesComponent, TenderDetailsComponent, PageNotFoundComponent, ConvertUrlPipe ],
providers : [ Globals,
{provide: RequestOptions, useClass: CustomRequestOptions}
],
bootstrap: [ AppComponent ]
})
现在,在我的组件类中,我在addHeader
中调用了CustomRequestOptions
方法。
export class LoginComponent {
private _token: string;
private _returnMsg: string;
constructor(private _usersService: UsersService, private _globals: Globals, private _customRequestOptions: CustomRequestOptions) {
}
onLoginFormSubmit(formData: any) {
this._usersService.login(formData.emailAddress, formData.password).subscribe(
returnRes => {
this._returnMsg = returnRes.returnMsg;
this._token = returnRes.token;
if (this._returnMsg == "SUCCESS") {
//sucess
console.log("AUTH SUCCESS");
let x = "Bearer " + this._token;
this._customRequestOptions.addHeader("Authorization", x);
this.getUserRoles(); //this call needs authorization header.
}
}
);
}
}
即使我使用this._customRequestOptions.addHeader("Authorization", x);
设置标头,下一个需要授权标头以便正常工作的调用也会失败。在服务器端,我可以看到,该部分为空。
这里有什么问题?
答案 0 :(得分:1)
扩展BaseRequestOptions
的问题是构造函数只在浏览器的生命周期中运行一次,除此之外,更改不会传播。而且,更改需要在super
调用中,如下所示:
super({
method: RequestMethod.Get,
headers: new Headers({
'Content-Type': 'application/json',
'X-Some-Header': 'some-content'
});
});
super
属性的headers
之外的操作不起作用。扩展BaseRequestOptions
的另一个选择是在模块中执行一次:
class DefaultRequestOptions extends BaseRequestOptions{
headers:Headers = new Headers({
'Content-Type': 'poop'
});
}
....
providers: [{provide: RequestOptions, useClass: DefaultRequestOptions}],
早期版本的Angular2中曾经有一种方法可以访问_defaultOptions
上的http
对象,但它现在已受到保护且无法访问。它看起来像这样:
this.http._defaultOptions.headers.set('Authorization', 'token');
<强> TLDR; 强>
如果您需要在应用程序的生命周期内更改标题,那么我建议您查看类似https://github.com/auth0/angular2-jwt
的内容或将自己的包装器写入http库(类似于angular2-jwt的工作方式) 。我已经编写了自己的分支来处理我的用例,之后我可以说“如果存在某些内容”,那么请执行 x &#39;。如果您决定写信给自己,那并不难,您可以查看https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts#L94的灵感。这将替换@ angular / http。
http
库
很抱歉,这可能不是您所寻求的解决方案,但这是我在尝试解决同一挑战时所学到的。希望它能够解释您的代码和潜在解决方案的问题。