setHeaders - resolvido

import {
  HttpErrorResponse,
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { AuthServerProvider } from '../auth/auth-jwt.service';
import { LoginService } from '../service/login.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(
    private loginService: LoginService,
    private auth: AuthServerProvider
  ) {}
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    request = this.set_request_header(request);
    return next.handle(request).pipe(
      retry(1),
      catchError((e: HttpErrorResponse) => {
        this.handle_error(e);
        return throwError(e);
      })
    );
  }
  private handle_error(e: HttpErrorResponse): void {
    if (e.status === 401 || e.status === 0) {
      this.loginService.logout();
    }
  }
  private set_request_header(request: any): any {
    if (!this.is_logar(request.url)) {
      request = request.clone({
        setHeaders: {
          Authorization: 'bearer ' + this.auth.getToken(),
        },
      });
    } else {
      request = request.clone({
        setHeaders: {
          Authorization: 'bearer ' + this.auth.getToken(),
          tipo_sistema: 'ROLE_CLIENTE',
        },
      });
    }
    return request;
  }
  private is_logar(url: any): boolean {
    let validacaoUrl = url.indexOf('oauth-api/oauth/token');
    return validacaoUrl != -1;
  }
}

Assim dá erro

import {
  HttpErrorResponse,
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { CLIENTE, SENHA } from '../api/erp.api';
import { AuthServerProvider } from '../auth/auth-jwt.service';
import { LoginService } from '../service/login.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(
    private loginService: LoginService,
    private auth: AuthServerProvider
  ) {}
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    request = this.set_request_header(request);
    return next.handle(request).pipe(
      retry(1),
      catchError((e: HttpErrorResponse) => {
        this.handle_error(e);
        return throwError(e);
      })
    );
  }
  private handle_error(e: HttpErrorResponse): void {
    if (e.status === 401 || e.status === 0) {
      this.loginService.logout();
    }
  }
  private set_request_header(request: any): any {
    if (!this.is_logar(request.url)) {
      request = request.clone({
        setHeaders: {
          Authorization: 'bearer ' + this.auth.getToken(),
        },
      });
    } else {
      request = request.clone({
        setHeaders: {
          Authorization: 'Basic ' + btoa(SENHA + ':' + CLIENTE),
        },
      });
    }
    return request;
  }
  private is_logar(url: any): boolean {
    let validacaoUrl = url.indexOf('oauth-api/oauth/token');
    return validacaoUrl != -1;
  }
}

Assim não dá erro

Será que é no back ?

O que pode ser ?

Qual foi o erro? 401?

1 curtida

Pelo que entendi dá erro de cors

Hehe, foi mal. Falta de atenção minha.

Mas estranho, pq no primeiro print tem 4 requisições, e 2 deram errado. Se uma deu certo, o CORS não deveria ser problema.

1 curtida

A que deu certo, é uma requisição OPTIONS

1 curtida

Este erro será por causa do spring ?

Alguma outra requisição funciona? Pq se tah dando problema de CORS, vc tem que configurar na aplicação para permitir requisições de outros dominios.

Obs.: Mesmo sendo localhost, portas diferentes já caracteriza domínios diferentes, ex: http://localhost:8080 e http://localhost:4200

1 curtida

Como disse no inicio

só da erro se ficar assim

      request = request.clone({
        setHeaders: {
          Authorization: 'bearer ' + this.auth.getToken(),
          tipo_sistema: 'ROLE_CLIENTE',
        },
      });

Se for assim não

request = request.clone({
        setHeaders: {
          Authorization: 'bearer ' + this.auth.getToken(),
        },
      });

Como teste, tente enviar o header sem usar underscore. Tente mandar "tipo-sistema": 'ROLE_CLIENTE',

Encontrei uma issue no github de um cara com um problema semelhante ao seu, e, no caso dele, era pq estava usando underscore no header. Veja: Custom headers from Angular App not sent to web api back-end · Issue #25159 · angular/angular · GitHub

Tentei assim

tipoSistema
tipo-sistema
tipo-Sistema
tipo_sistema
tipo_Sistema

e nada

Se vc depurar o backend, o header tipo-sistema chega preenchido?

1 curtida

Tente também fazer o clone dessa forma:

request = request.clone({
  headers: request.headers
    .set('Authorization', 'Bearer ' + this.auth.getToken())
    .set('tipo_sistema', 'ROLE_CLIENTE')
});
1 curtida

Como o prórpio erro informa.

Request header field tiposistema is not allowed by Access-Control-Allow-Headers in preflight response.
zone.js:2863 POST http://localhost:9100/oauth-api/oauth/token?grant_type=password&username=guilhermea@netsoft.eti.br&password=gui417net::ERR_FAILED

Fui olhar no cors, está assim

package br.com.ghnetsoft.gestaovendasatendimento.oauth.config;

import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Order(HIGHEST_PRECEDENCE)
@Slf4j
@Component
public class SmpleCORSFilter implements Filter {

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        log.info("Sistema de usuario permissao para administrador | SmpleCORSFilter inicio");
    }

    @Override
    public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) resp;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, resp);
        }
    }

    @Override
    public void destroy() {
        //
    }
}

Mudei esta linha de

response.setHeader(“Access-Control-Allow-Headers”, “x-requested-with, authorization, Content-Type, Authorization”);

para

response.setHeader(“Access-Control-Allow-Headers”, “x-requested-with, authorization, Content-Type, Authorization, tipoSistema”);

E funcionou.

O problema não era no angular e sim no back

Tanto assim no angular

      request = request.clone({
        setHeaders: {
          Authorization: 'Basic ' + btoa(SENHA + ':' + CLIENTE),
          tipoSistema: 'ROLE_CLIENTE',
        },
      });

ou assim funciona

request = request.clone({
  headers: request.headers
    .set('Authorization', 'Bearer ' + this.auth.getToken())
    .set('tipo_sistema', 'ROLE_CLIENTE')
});

Obrigado @Lucas_Camara