Como definir corretamente o header de solicitação HTTP em Angular 2

Eu tenho um aplicativo Ionic 2 usando Angular 2, que está enviando um Http PUT para um servidor ASP.NET Core API. Aqui está o método que estou usando para enviar a solicitação:

public update(student: Student): Promise { let headers = new Headers(); headers.append('Content-Type', 'application/json'); headers.append('authentication', `${student.token}`); const url = `${this.studentsUrl}`; return this.http .put(url, JSON.stringify(student), { headers: headers }) .toPromise() .then(() => student) .catch(this.handleError); } 

Estou definindo uma chave / valor de autenticação no object de header.

Mas quando recebo este pedido no servidor, não consigo encontrar a chave de autenticação no header:

insira a descrição da imagem aqui

Como você pode ver na figura, há muitas chaves no header, mas não as chaves de conteúdo e autenticação que adicionei manualmente ao header no aplicativo cliente.

O que estou fazendo de errado?

Seu parâmetro para as opções de solicitação em http.put () deve, na verdade, ser do tipo RequestOptions. Tente algo assim:

 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) 

Angular 4>

Você pode optar por definir os headers manualmente ou criar um interceptor HTTP.

Pré-requisitos para Angular <4.3:

Por favor, certifique-se de usar @angular/common/http toda a sua aplicação (isto mudou em Angular 4.3).

  • Migrar para o módulo HttpClient
  • Aqui você pode encontrar o guia Angular no HttpClient.

Manualmente

A class HttpHeaders é imutável, portanto, cada conjunto () retorna uma nova instância e aplica as mudanças.

Dos documentos angulares.

Definindo um header:

 http .post('/api/items/add', body, { headers: new HttpHeaders().set('Authorization', 'my-auth-token'), }) .subscribe(); 

Definindo vários headers:

 this.http .post('api/items/add', body, { headers: new HttpHeaders({ 'Authorization': 'my-auth-token', 'x-header': 'x-value' }) }).subscribe() 

Variável local (instante imutável novamente)

 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() 

Interceptor HTTP

Uma das principais características de @ angular / common / http é a interceptação, a capacidade de declarar interceptores que se situam entre a sua aplicação e o backend. Quando seu aplicativo faz uma solicitação, os interceptores o transformam antes de enviá-lo para o servidor, e os interceptores podem transformar a resposta no caminho de volta antes que o aplicativo a veja. Isso é útil para tudo, desde autenticação até o registro.

Dos documentos angulares.

Certifique-se de usar @angular/common/http todo o seu aplicativo. Dessa forma, seus pedidos serão capturados pelo interceptador.

Etapa 1, crie o serviço:

 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, next: HttpHandler): Observable> { if (true) { // eg 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); } } } 

Etapa 2, adicione-o ao seu módulo:

 providers: [ { provide: HTTP_INTERCEPTORS, useClass: HeaderInterceptor, multi: true // Add this line when using multiple interceptors. }, // ... ] 

Links Úteis:

  • Interceptor não está funcionando corretamente .
  • APP_INITIALIZER não funciona em combinação com o interceptor

Isso deve ser facilmente resolvido importando headers do Angular:

 import { Http, Headers } from "@angular/http"; 

Nós podemos fazer isso muito bem usando Interceptores . Você não precisa definir opções em todos os seus serviços nem gerenciar todas as suas respostas de erro, basta definir dois interceptores (um para fazer algo antes de enviar a solicitação ao servidor e um para fazer algo antes de enviar a resposta do servidor ao seu serviço)

  1. Defina uma class AuthInterceptor para fazer algo antes de enviar a solicitação ao servidor. Você pode definir o token da API (recuperá-lo do localStorage, consulte a etapa 4) e outras opções dessa class.
  2. Defina uma class responseInterceptor para fazer algo antes de enviar a resposta do servidor ao seu serviço (httpClient). Você pode gerenciar sua resposta do servidor, o uso mais comum é verificar se o token do usuário é válido (se não limpar o token do localStorage e redirect para o login).
  3. Em seu app.module, importe HTTP_INTERCEPTORS de ‘@ angular / common / http’. Em seguida, adicione aos seus provedores os interceptores (AuthInterceptor e responseInterceptor). Fazendo isso, seu aplicativo considerará os interceptores em todas as nossas chamadas httpClient.

  4. Na resposta http de login (use o serviço http ), salve o token em localStorage.

  5. Em seguida, use o httpClient para todos os seus serviços.

Você pode conferir algumas boas práticas no meu projeto github aqui

insira a descrição da imagem aqui

Você tem um erro de digitação.

Alteração: headers.append('authentication', ${student.token});

Para: headers.append('Authentication', student.token);

OBSERVAÇÃO a autenticação é maiúscula

Para nós, usamos uma solução como esta:

 this.http.get(this.urls.order + '&list', { headers: { 'Cache-Control': 'no-cache', } }).subscribe((response) => { ... 

Referência aqui