Мы развернули веб-приложение Laravel 10 — React JS на сервере Windows.
API работает, попробовал на почтальоне. Веб-страницы для нашего внешнего интерфейса также работают, за исключением случаев выполнения API. Ниже отображается ошибка Cors:
Доступ к XMLHttpRequest по адресу «https://api.mydomain.com/sign-in» из источника «https://webapp.mydomain.com» заблокирован политикой CORS: ответ на предполетный запрос не проходит проверку контроля доступа : в запрошенном ресурсе отсутствует заголовок Access-Control-Allow-Origin.
Я уверен, что я правильно настроил .env и cors.php, включил промежуточное программное обеспечение Cors. Кроме того, он работает в моей локальной среде только с localhost: 8000 и localhost: 3000.
Есть ли кто-нибудь с такой же проблемой? Как вы, ребята, это решаете?
Вот код:
cors.php
<?php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie', 'sign-in', 'sign-out'],
'allowed_methods' => ['*'],
'allowed_origins' => [env('FRONTEND_URL', 'https://webapp.mydomain.com')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
Ларавел: .env
APP_URL=https://api.mydomain.com
FRONTEND_URL=https:/webapp.mydomain.com
SANCTUM_STATEFUL_DOMAINS=webapp.mydomain.com
SESSION_DOMAIN=mydomain.com
Реакция: .env
VITE_API_BASE_URL=https://api.mydomain.com
веб.конфигурация
<?xml version = "1.0" encoding = "UTF-8"?>
<configuration>
<system.webServer>
code here...
<httpProtocol>
<customHeaders>
<add name = "Access-Control-Allow-Origin" value = "https://webapp.mydomain.com" />
<add name = "Access-Control-Allow-Methods" value = "GET, POST, PUT, DELETE, OPTIONS" />
<add name = "Access-Control-Allow-Headers" value = "Content-Type, Authorization" />
<add name = "Access-Control-Allow-Credentials" value = "true" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
axios-client.js
import axios from 'axios';
import csrfCookie from './csrf-cookie';
const api = axios.create({
baseURL: `${import.meta.env.VITE_API_BASE_URL}/api/v1`,
withCredentials: true,
})
const web = axios.create({
baseURL: `${import.meta.env.VITE_API_BASE_URL}`,
withCredentials: true,
})
const apiBase = `${import.meta.env.VITE_API_BASE_URL}/api/v1`
const webBase = `${import.meta.env.VITE_API_BASE_URL}`
export { api, web, apiBase, webBase };
Код входа
import { api, web } from "../axios-client"
import csrfCookie from "../csrf-cookie"
await csrfCookie().catch(err => {
code here...
})
await web.post('/sign-in', formData)
.then(async ({ data }) => {
code here...
})
.catch(err => {
code here...
})
}
Я попытался переместить свои пользовательские заголовки из web.config React в web.config Laravel. Однако это привело к новой ошибке:
Заголовок Access-Control-Allow-Origin содержит несколько значений «https://webapp.mydomain.com, https://webapp.mydomain.com», но разрешено только одно.
<customHeaders>
<add name = "Access-Control-Allow-Origin" value = "https://webapp.mydomain.com" />
<add name = "Access-Control-Allow-Methods" value = "GET, POST, PUT, DELETE, OPTIONS" />
<add name = "Access-Control-Allow-Headers" value = "Content-Type, Authorization" />
<add name = "Access-Control-Allow-Credentials" value = "true" />
</customHeaders>
</httpProtocol>
Когда я удалил customHeaders из web.config Laravel, это привело к ошибке «No Access-Control-Allow-Origin». Добавление его обратно снова вызвало ошибку с несколькими значениями заголовков. Затем я попытался удалить URL-адрес внешнего интерфейса из «allowed_origins» в cors.php, что, наконец, решило проблему.
cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie', 'sign-in', 'sign-out'],
'allowed_methods' => ['*'],
'allowed_origins' => [/*Removed frontend url here*/],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
Вы можете рассмотреть возможность создания промежуточного программного обеспечения для пользовательских ответов заголовков.
class CorsMiddleware {
public function handle($request, Closure $next)
{
//Intercepts OPTIONS requests
if ($request->isMethod('OPTIONS')) {
$response = response('', 200);
} else {
// Pass the request to the next middleware
$response = $next($request);
}
// Adds headers to the response
$response->header('Access-Control-Allow-Methods', '*');
$response->header('Access-Control-Allow-Headers', '*');
$response->header('Access-Control-Allow-Origin', env('FRONTEND_URL', 'https://webapp.mydomain.com'));
return $response;
}
}
Затем примените это промежуточное ПО к своему API.