I have an Ionic 2 application using Angular 2, which is sending an Http PUT to a ASP.NET Core API server. Here\'s the method I\'m using to send the request:
You can either choose to set the headers manually, or make an HTTP interceptor that automatically sets header(s) every time a request is being made.
Setting a header:
http
.post('/api/items/add', body, {
headers: new HttpHeaders().set('Authorization', 'my-auth-token'),
})
.subscribe();
Setting headers:
this.http
.post('api/items/add', body, {
headers: new HttpHeaders({
'Authorization': 'my-auth-token',
'x-header': 'x-value'
})
}).subscribe()
Local variable (immutable instantiate again)
let headers = new HttpHeaders().set('header-name', 'header-value');
headers = headers.set('header-name-2', 'header-value-2');
this.http
.post('api/items/add', body, { headers: headers })
.subscribe()
The HttpHeaders class is immutable, so every set() returns a new instance and applies the changes.
From the Angular docs.
A major feature of @angular/common/http is interception, the ability to declare interceptors which sit in between your application and the backend. When your application makes a request, interceptors transform it before sending it to the server, and the interceptors can transform the response on its way back before your application sees it. This is useful for everything from authentication to logging.
From the Angular docs.
Make sure you use @angular/common/http
throughout your application. That way your requests will be catched by the interceptor.
Step 1, create the service:
import * as lskeys from './../localstorage.items';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '@angular/common/http';
@Injectable()
export class HeaderInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (true) { // e.g. if token exists, otherwise use incomming request.
return next.handle(req.clone({
setHeaders: {
'AuthenticationToken': localStorage.getItem('TOKEN'),
'Tenant': localStorage.getItem('TENANT')
}
}));
}
else {
return next.handle(req);
}
}
}
Step 2, add it to your module:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HeaderInterceptor,
multi: true // Add this line when using multiple interceptors.
},
// ...
]
Useful links:
Your parameter for the request options in http.put() should actually be of type RequestOptions. Try something like this:
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('authentication', `${student.token}`);
let options = new RequestOptions({ headers: headers });
return this.http
.put(url, JSON.stringify(student), options)
For us we used a solution like this:
this.http.get(this.urls.order + '&list', {
headers: {
'Cache-Control': 'no-cache',
}
}).subscribe((response) => { ...
Reference here
This should be easily resolved by importing headers from Angular:
import { Http, Headers } from "@angular/http";
You have a typo.
Change: headers.append('authentication', ${student.token});
To: headers.append('Authentication', student.token);
NOTE the Authentication is capitalized
We can do it nicely using Interceptors. You dont have to set options in all your services neither manage all your error responses, just define 2 interceptors (one to do something before sending the request to server and one to do something before sending the server's response to your service)
In your app.module import HTTP_INTERCEPTORS from '@angular/common/http'. Then add to your providers the interceptors (AuthInterceptor and responseInterceptor). Doing this your app will consider the interceptors in all our httpClient calls.
At login http response (use http service), save the token at localStorage.
Then use httpClient for all your apirest services.
You can check some good practices on my github proyect here