2017-06-11 51 views
6

Więc wiem, że jest tam wiele postów CORS, a ja tylko dodam do nich, ale nie mogę znaleźć żadnych odpowiedzi, które by mi pomogły. Więc buduję 4-kątną aplikację, która opiera się na moim php api. Praca lokalnie jest w porządku, moment mogę wrzucić go na domenie z aplikacji w app.example.com i api na api.example.com, nie mogę ominąć mojego loginu, ponieważ pojawia się następujący błąd:CORS: PHP: Odpowiedź na żądanie sprawdzenia wstępnego nie przechodzi. Jestem zezwalam na pochodzenie

XMLHttpRequest cannot load http://api.example.com/Account/Login . Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ' http://app.example.com ' is therefore not allowed access.

My kod php wygląda następująco:

$http_origin = $_SERVER['HTTP_ORIGIN']; 

$allowed_domains = array(
    'http://example.com', 
    'https://example.com', 
    'http://app.example.com', 
    'https://app.example.com', 
    'http://www.example.com', 
    'https://www.example.com' 
); 

if (in_array(strtolower($http_origin), $allowed_domains)) 
{ 
    // header("Access-Control-Allow-Origin: *"); 
    header("Access-Control-Allow-Origin: $http_origin"); 
    header('Access-Control-Allow-Credentials: true'); 
    header('Access-Control-Max-Age: 86400'); 
} 

// Access-Control headers are received during OPTIONS requests 
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 
     header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
     header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin"); 
    exit(0); 
} 

Moja słup narożny wygląda następująco:

public login(login: Login): Observable<LoginResponse> { 
    let headers = new Headers(); 
    headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
    headers.append('Authorization', 'Basic ' + btoa(login.Username + ':' + login.Password)); 
    return this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers }) 
     .map(response => { 
      // code 
     }); 
} 

Gdybym uruchomić żądanie za pośrednictwem listonosza, który nie przeszkadza w CORS, ja ge T:

{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" } 

Próbowałem ustawienie pochodzenie „*” tylko przetestować i zobaczyć, czy to było sedno problemu, a to jeszcze nie w ten sam sposób.

Edit Wystarczy aktualizacji z informacjami poniżej. Zmiana obudowy w nagłówkach nie przyniosła skutku, a wyciągnięcie kodu z ich instrukcji if nie przyniosło żadnego efektu.

I debugowałem php, mówiąc mojej aplikacji na żywo, aby przejść do mojego lokalnego API, a php działa zgodnie z oczekiwaniami. Ustawia nagłówki i czyni je w każdym z instrukcji if.

Edit Take 2 Mogłem naprawdę jakaś pomoc na ten jeden, jeśli ktoś ma jakieś pomysły, będę naprawdę wdzięczny.

Edit wziąć 3 Jeżeli ustawić wszystkie rzeczy nagłówka w moim .htaccess zamiast mojego php, że pozwala mi przejść. Jednak teraz utknąłem na powyższym błędzie, który zawsze pojawia się podczas korzystania z listonosza, jednak teraz jest to podczas korzystania z rzeczywistej witryny.

{"error":"invalid_client","error_description":"Client credentials were not found in the headers or body"}

nagłówki moja odpowiedź jest jak tak

Access-Control-Allow-Credentials:true 
Access-Control-Allow-Headers:authorization, content-type, accept, origin 
Access-Control-Allow-Methods:GET, POST, OPTIONS 
Access-Control-Allow-Origin:* 

będę zmieniając go od * do moich domen tylko raz I to działa. Ale na razie zostawię to jako *.

Moje nagłówki zgodnie z życzeniem.

Headers for failed request

+0

wyjąć kod z if ($ _SERVER ['REQUEST_METHOD'] == 'OPCJE') {sprawdź, co się stało. – MasoodUrRehman

+0

Czy możesz udostępnić migawkę odpowiedzi serwera, sprawdzając kartę sieci w przeglądarce? – MasoodUrRehman

+0

Zakładka odpowiedź w debuggera jest pusty, ale oto nagłówki - Odpowiedź: 'ce: post, Opcje, GET, HEAD, TRACE Connection: keep-alive Content-Length: 0 Content-Type: text/plain Data: Sun, 11 czerwca 2017 02:41:43 GMT keep-alive: timeout = 30 Server: Apache/2' Zapytanie: 'Accept: */* Accept-Encoding: gzip, deflate Zaakceptuj język: en-US, en; q = 0,8, ca; q = 0,6 Access-Control-Request-Headers: autoryzacja Access-Control-Request-Method: POST Połączenie: keep-alive Host: api. egzamin ple.com Pochodzenie: http: //app.example.com Referer: http: // app.example.com/login' – Nieminen

Odpowiedz

0

OK miałem podobne problemy, a ja niedawno rozwiązany wszystko tylko od strony zaplecza, bez .htaccess rzeczy.

kiedy przeglądarka wysyła żądania między serwerami, wysyła najpierw żądanie OPTIONS, aby upewnić się, że jest prawidłowe i może wysłać "prawdziwe" żądanie. Po uzyskaniu poprawnej i prawidłowej odpowiedzi z OPCJI, tylko wtedy wysyła "prawdziwą" prośbę.

Teraz zarówno żądanie w backend trzeba się upewnić, aby przywrócić odpowiednie nagłówki: content-type, pozwalają pochodzenia, allow-nagłówki itp ...

Upewnij się, że w OPCJI zwrócić na aplikacja zwraca nagłówki i zwraca odpowiedź, nie kontynuując pełnego przepływu aplikacji.

W "prawdziwym" żądaniu powinieneś zwrócić odpowiednie nagłówki i swoją zwykłą treść odpowiedzi.

przykład:

//The Response object 
    $res = $app->response; 

    $res->headers->set('Content-Type', 'application/json'); 
    $res->headers->set('Access-Control-Allow-Origin', 'http://example.com'); 
    $res->headers->set('Access-Control-Allow-Credentials', 'true'); 
    $res->headers->set('Access-Control-Max-Age', '60'); 
    $res->headers->set('Access-Control-Allow-Headers', 'AccountKey,x-requested-with, Content-Type, origin, authorization, accept, client-security-token, host, date, cookie, cookie2'); 
    $res->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); 

    if (! $req->isOptions()) { 
     // this continues the normal flow of the app, and will return the proper body 
     $this->next->call(); 
    } else { 
     //stops the app, and sends the response 
     return $res; 
    } 

warte zapamiętania:

  • jeśli używasz: "Access-Control-allow-Poświadczenia" = true upewnij się, że „Access-Control-Allow -Origin "nie jest" * ", musi być ustawiony z odpowiednią domeną! (dużo krwi rozlał tutaj: /)

  • zdefiniowanie dozwolonych nagłówki dostaniesz w "Access-Control-Allow-headers" jeśli przyzwyczajenie je zdefiniować, wniosek zawiedzie

+0

Nie mogę tego jeszcze przetestować, ale brzmi to nieźle. Zamierzam iść dalej i zaakceptować odpowiedź, abyś mógł otrzymać nagrodę, zanim wygaśnie. Dzięki! – Nieminen

+0

Dzięki :) Jeśli to nie zadziała, prosimy o komentarz, dopóki go nie rozwiążemy. Tyle tygodni temu straciłem tyle czasu, więc mam na myśli haha ​​ –

+0

. Czy mógłbyś mi spojrzeć na podobny problem? https://stackoverflow.com/questions/44751329/php-cors-oauth2-bearer-token-authorization-issues – Nieminen

0

Dodałem poniżej w php i to rozwiązało mój problem.

header("Access-Control-Allow-Origin: *"); 

header("Access-Control-Allow-Headers: Content-Type, origin");