it-swarm.com.de

Die Antwort auf Preflight hat nicht den Status "HTTP OK" in Winkel

Ich habe die folgende Get-Anfrage in meinem Service definiert:

createAuthorizationHeader(user, pass) {
  let headers: HttpHeaders = new HttpHeaders;
  headers = headers.append('Accept', 'application/json, text/plain, */*');
  headers = headers.append('Authorization', 'Basic ' + btoa(user + ':' + pass));
  headers = headers.append('Content-Type', 'application/json; charset=utf-8');
    console.log(headers);
    return this.http.get(this._loginUrl, {
      headers: headers
    });
}

Das Ergebnis ist:

OPTIONS https://localhost:8443/delivery/all 401 ()

Failed to load https://localhost:8443/delivery/all: Response for preflight does not have HTTP ok status.

HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}

Ich habe auch dieselbe Post-Anfrage mit Postman gemacht, aber alles funktioniert, also der lokale Server.

Ich kann nicht herausfinden, was ich falsch mit meiner Anfrage mache.

16
KalinJa

Der CORS-Vertrag erfordert, dass für die OPTIONS-Anfrage vor dem Flug keine Authentifizierung erforderlich ist. Es sieht so aus, als ob Ihr Backend eine Authentifizierung für die OPTIONS-Anfrage und den GET erfordert.

Wenn Sie mit Postman auf Ihr Backend zugreifen, senden Sie nur ein GET . Der Browser sendet zuerst eine OPTIONS-Anforderung (ohne Ihren Authentifizierungsheader) und sucht nach der Antwort, um ein "Access-Control-Allow- Origin "Header, der mit dem Origin der Seite übereinstimmt, von der die Anforderung stammt.

Wenn die Antwort auf die Antwort OPTIONS nicht 2xx ist oder der Header nicht vorhanden ist oder der Wert des Headers nicht mit dem Ursprung der anfordernden Seite übereinstimmt, wird der Fehler angezeigt, den Sie erhalten, und die GET-Anforderung wird nicht gestellt .

TLDR; Ändern Sie Ihr Backend so, dass für die Methode OPTIONS keine Authentifizierung erforderlich ist, wenn Sie die Anmelde-URL verarbeiten.

24
GreyBeardedGeek

Standardmäßig erlauben Browser keinen Benutzern die Durchführung von Cross-Origin-Anforderungen.

Um diesen Fehler zu vermeiden, können wir die Proxy-Konfiguration verwenden.

Angenommen, das Winkel-UI arbeitet mit localhost: 4200 und möchte die URL für den Restendpunkt aufrufen, z. B .: https: // localhost: 8443/delivery/all

Die folgenden Schritte werden dieses Problem beheben.

  1. Erstellen Sie eine proxy.config.json-Datei im Root-Ordner der eckigen Anwendung. (Wenn die package.json-Datei vorhanden ist.) Der Proxy nimmt einfach die Browseranforderung an die Domäne + den Port an, an dem die Frontend-Anwendung ausgeführt wird, und leitet diese Anforderung an den Backend-API-Server weiter. CORS ist ein Sicherheitsproblem für Browser und gilt nicht für die Kommunikation "Backend to Backend" wie bei einem dazwischen befindlichen Proxy.

    Der Inhalt sollte wie folgt aussehen.

    Probe: 

    {
        "/delivery/all/*": {
        "target": "https://localhost:8443",
        "secure": false,
        "logLevel": "debug",
        "changeOrigin": true
        }
    }
    

    Alle Anfragen an/delivery/all/... aus unserer Anwendung werden an https: // localhost: 8443/delivery/all/ weitergeleitet.

    Anmerkung: Die changeOrigin-Eigenschaft. Sie müssen diesen Wert definitiv auf true setzen, wenn Sie virtuelle Proxys (z. B. mit Apache2 konfiguriert) in Ihrem Backend verwenden

  2. Fügen Sie während der Anwendung eine Proxy-Konfiguration hinzu. Angular unterstützt "--proxy-config", wo Sie die Proxy-Konfigurationsdatei angeben können. Wenn Sie die Option "npm start" zum Testen verwenden, müssen Sie die Option "--proxy-config" wie unten angegeben hinzufügen. Es muss in der package.json-Datei hinzugefügt werden.

     "scripts": {
    
    "ng": "ng",
    "start": "ng serve --proxy-config proxy.config.json",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
    }
    

    Wenn Sie direkt mit "ng serv" arbeiten, wurde es wie folgt geändert. "ng dienen --proxy-config proxy.config.json"

  3. Der HTTP-Aufruf in unserer Angular-Anwendung kann darauf geändert werden. Der Server leitet die Anforderung automatisch an " https: // localhost: 8443/delivery/all " weiter.

    this.http.get (' https: // localhost: 8443/delivery/all ') .map (res => res.json ());

    zu

    this.http.get ('/ delivery/all') .map (res => res.json ());

hier finden Sie einen Link zu weiteren Informationen: https://sudhasoftjava.wordpress.com/2018/10/05/proxy-configuration-in-angular/

5
Sudhakar

@Daryl

Wir haben eine benutzerdefinierte Konfiguration für Cors hinzugefügt. Aktivieren Sie es dann über die Sicherheitskonfiguration auf dem Java-Server. Dieser Server wurde nur für direkte REST - Aufrufe aktiviert, wie in der Antwort erläutert.

@Configuration
public class CorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                        .allowedHeaders("*");
            }
        };
    }
}

Und das geht in die Web-Sicherheitskonfiguration ein:

@Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable()
                .antMatcher("/**")
                .authorizeRequests().and()
                .httpBasic()
                .and()
                .authorizeRequests().anyRequest().authenticated().and().cors();
    }
0
thunder88