Reputation: 2113
I need an Authorization header to be appended to each and every HTTP request done by my Angular2 app.
The first request would be the login request, which does not have an authorization header. Once the login in is successful, a token is returned from the server and I need that to be appended as an authorization header to each and every subsequent HTTP requests.
I am getting the the token from the server without any problem. I can log in successfully using my angular2 app. But the problem is, the token is not attached to subsequent request headers.
This is my implementation.
I have created a CustomRequestOptions class extending the BaseRequestOptions class.
@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);
}
}
I have added that to @NgModule
in order for this CustomRequestOptions
to be global.(to be visible across all the components)
@NgModule({
imports: [ BrowserModule, HttpModule, routing, FormsModule ],
declarations: [ AppComponent, TendersComponent, TenderCategoriesComponent, TenderDetailsComponent, PageNotFoundComponent, ConvertUrlPipe ],
providers : [ Globals,
{provide: RequestOptions, useClass: CustomRequestOptions}
],
bootstrap: [ AppComponent ]
})
Now, in my component class, I am calling the addHeader
method in 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.
}
}
);
}
}
Even though I set the header using this._customRequestOptions.addHeader("Authorization", x);
, the next call, which needs Authorization header in order to work properly, fails. In server side,I can see, that part is null.
What is wrong here?
Upvotes: 1
Views: 1848
Reputation: 8911
The problem of extending BaseRequestOptions
is that the constructor is only run once in the lifetime of the browser and beyond that, the changes will not propagate. And, the changes would need to be in the super
call like this:
super({
method: RequestMethod.Get,
headers: new Headers({
'Content-Type': 'application/json',
'X-Some-Header': 'some-content'
});
});
Manipulation outside of super
of the headers
property does not work. The other option in extending the BaseRequestOptions
is to do it once in your module:
class DefaultRequestOptions extends BaseRequestOptions{
headers:Headers = new Headers({
'Content-Type': 'poop'
});
}
....
providers: [{provide: RequestOptions, useClass: DefaultRequestOptions}],
There used to be a way in earlier versions of Angular2 where you could access the _defaultOptions
object on http
, but it is now protected and inaccessible. It looked like this:
this.http._defaultOptions.headers.set('Authorization', 'token');
TLDR;
If you need to change headers during the lifetime of your application then I'd suggest looking at something like https://github.com/auth0/angular2-jwt
or writing your own wrapper to the http library(similar to how angular2-jwt does it). I've written my own fork to handle my use cases before where I can say 'if something exists, then do x'. If you decide to write you're own, it's not that difficult, you can look at https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts#L94 for inspiration. This would replace the normal http
library in @angular/http.
Sorry, that is probably not the solution you were looking for, but this is what I've learned trying to tackle the same challenge. Hope it sheds some light on the problem with your code and potential solutions.
Upvotes: 1