Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Token não consta no header da response do meu backend

Olá professor estou cursando o curso de Angular e junto AspnetCore RestFull aqui na Alura, aprendi gerar o token com aspnet core através do JWT, ele gera com sucesso com resposta 200 Ok, porém o token está vindo no body, nos testes com postman o header consta apenas isso:

Date →Wed, 06 Feb 2019 00:07:44 GMT
Content-Type →application/json; charset=utf-8
Server →Kestrel
Transfer-Encoding →chunked

e na guia body consta:

{
    "id": 1,
    "firstName": "Test",
    "lastName": "User",
    "username": "test",
    "password": null,
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjEiLCJuYmYiOjE1NDk0MTE2NjQsImV4cCI6MTU1MDAxNjQ2NCwiaWF0IjoxNTQ5NDExNjY0fQ.CpPKzDtLJ9wSSuI-4crt10zdA0FWPwZXfZluhoAUIdg"
}

Gostaria de saber se existe a possibilidade de obter o token vindo pelo body e não pelo header?

3 respostas
solução!

Olá Alberto, normalmente o fluxo é o seguinte:

1) O resultado da requisição da autenticação deve pegar o token e salvar em algum lugar para as futuras requisições que precisarão enviar o token no header. Normalmente usa-se o localStorage.

2) Qdo for realizar uma requisição que precise de token, obtenha o mesmo do local onde salvou (por exemplo do localStorage) e coloque no header.

Segue abaixo algum exemplo demonstrando estes passos:

protected headers(): HttpHeaders {
    return new HttpHeaders({
      'Content-Type': 'application/json'
    });
  }

protected securityHeaders(): HttpHeaders {
    return new HttpHeaders({
      'Content-Type': 'application/json',
      'Authorization': this.getToken()
    });
  }

protected getToken(): string {
    const currentUser = JSON.parse(localStorage.getItem('currentUser'));
    const token = currentUser && currentUser.token;

    return token ? token : '';
  }

hasToken(): boolean {
    const jwt = this.getToken();

    return jwt != null && jwt !== '';
  }

protected deductHeader() {
    return {headers: this.hasToken() ? this.securityHeaders() : this.headers()};
  }

Os métodos acima pertencem a uma classe chamada BaseService, donde qualquer classe de Service extende.

addProduct(shoppingCart: ShoppingCart, product: Product): Observable<ShoppingCartItem> {
    const payload: any = { shopping_cart_item: { product_id: product.id } };

    return this.httpClient.post<ShoppingCartItem>(this.urlItems(shoppingCart.id),
      JSON.stringify(payload),
      this.deductHeader()
    );
  }

O método addProduct é de uma classe ShoppingCartService, que extend BaseService.

Como pode ser percebido addProduct realiza um POST, e no header ele usa o método herdado chamado deductHeader.

A lógica do deductHeader é criar um header com o token, caso ele exista ou sem o token caso ele não exista. Naturalmente se o backend espera o token e o mesmo não for enviado provavelmente ocorrerá um 404 - Not Authorized.

Alberto não é um exemplo muito didático, mas estou usando em aplicações reais.

Espero que ajude.

Att.

Muito obrigado pela ajuda. É que no curso de angular o conteúdo está ensinando puxar o token desta forma:

return this.http
    .post(
        API_URL + '/user/login', 
        { userName, password } 
    )
    .pipe(tap(res => {
        const authToken = res.headers.get('x-access-token')
        console.log(`User ${userName} authenticated with token ${authToken}`);
    }));

Porém agora com o localStorage está funcionando:

return this.http.post<any>(API_URL+'/api/logar', { username, password })
    .pipe(map(user => {
      //login sucessfull
      this.menuEmitter.emit(true);
      if(user && user.token){
        const authToken = user.token;
        console.log("meu token: " + authToken);
        // store user details and jwt token in local storage to keep user logged in between page refreshes        
        localStorage.setItem('currentUser', JSON.stringify(user));
      }
      return user;
    }));

No primeiro pipe faltou armazenar o token para uso posterior. Como feito no segundo, onde utilizastes o localStorage.

Att.