angular — CORS: PHP: Ответ на предполетный запрос не проходит. Разрешаю происхождение

Так что я знаю, что есть много публикаций CORS, и я просто добавляю к ним, но я не могу найти ни одного с ответами, которые помогут мне. Итак, я создаю угловое приложение, основанное на моем php api. Работать локально это нормально, в тот момент, когда я добавляю его в домен с приложением в app.example.comи API в api.example.com, Я не могу пройти мой логин, потому что я получаю следующую ошибку:

XMLHttpRequest не может загрузить http://api.example.com/Account/Login.
Ответ на предполетный запрос не проходит проверку контроля доступа: Нет
Заголовок «Access-Control-Allow-Origin» присутствует в запрошенном
ресурс. Происхождениеhttp://app.example.comПоэтому не допускается
доступ.

Мой PHP-код выглядит так:

$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);
}

Мой угловой пост выглядит так:

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
});
}

Если я выполню запрос через почтальона, который не беспокоится о CORS, я получу:

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

Я пытался установить происхождение «*«просто чтобы проверить и убедиться, что это было ядром проблемы, и это все равно не получается.

редактировать
Просто обновление из информации ниже. Изменение регистров в заголовках не имело никакого эффекта, а извлечение кода из их операторов if не имело никакого эффекта.

Я отладил php, сказав, что мое живое приложение должно перейти на локальный api, и php работает как положено. Это установка заголовков и включение их в каждое из операторов if.

Изменить дубль 2
Я мог бы действительно использовать некоторую помощь по этому вопросу, если у кого-то есть какие-либо идеи, я был бы очень признателен.

Изменить дубль 3
Если я установлю все содержимое заголовка в моем .htaccess, а не в своем php, он пропустит меня. Тем не менее, теперь я застрял на вышеупомянутой ошибке, которую я всегда получаю при использовании почтальона, однако теперь это происходит при использовании реального сайта.

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

Мои заголовки ответа выглядят так

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:*

Я поменяю его с * на только мои домены, как только он заработает. Но сейчас я оставлю это как *.

Мои заголовки по запросу.

Заголовки для неудачного запроса

7

Решение

Хорошо, у меня недавно были похожие проблемы, и я решил все только на бэкэнде без .htaccess.

когда браузер отправляет межсерверные запросы, он сначала отправляет запрос OPTIONS, чтобы убедиться, что он действителен и может отправлять «реальный» запрос.
После того, как он получает правильный и действительный ответ от OPTIONS, только тогда он отправляет «реальный» запрос.

Теперь для обоих запросов к бэкэнду необходимо убедиться, что возвращены правильные заголовки: content-type, allow-origin, allow-headers и т.д …

Убедитесь, что в запросе OPTIONS на бэкэнде приложение возвращает заголовки и возвращает ответ, не продолжая весь поток приложения.

В «реальном» запросе вы должны вернуть правильные заголовки и ваше тело регулярного ответа.

пример:

    //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;
}

То, что нужно запомнить:

  • если вы используете: «Access-Control-Allow-Credentials» = true
    убедитесь, что «Access-Control-Allow-Origin» не является «*», он должен быть установлен с соответствующим доменом!
    (здесь пролилось много крови: /)

  • определить разрешенные заголовки, которые вы получите в «Access-Control-Allow-Headers», если вы не определите их, запрос не будет выполнен

1

Другие решения

Я добавил ниже в php, и это решило мою проблему.

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

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

По вопросам рекламы [email protected]