Symfony3: 404 на DEV, 403 на PROD с ответом контроллера
Я в растерянности...
Я делаю AJAX POST для Symfony. В среде PROD (app.php) я получаю код состояния 403 FORBIDDEN (у пользователя есть доступ), но ответ содержит сообщение об ошибке, которое генерируется внутри контроллера для одного из пустых параметров POST. Я определил, что $request->request->all() пусто. Переключаясь на среду DEV (app_dev.php), я получаю ответ 404 NOT FOUND. Просмотр маршрута на PROD & DEV не дает ни 403, ни 404 ответов. AJAX POST находится на том же сервере (без междоменной проблемы), и Symfony создает маршрут для AJAX POST.
Пара заметок:
1) Код работает на моем локальном хосте без нареканий. Проблема возникает только на нашем производственном сервере. Security.yml настроен правильно, и я деактивировал пользовательский ExceptionListener. Ошибка 404 НЕ НАЙДЕНА в PROD - это стандартный Apache 404, а не Symfony 404 "Route Not Found". Однако, когда я включаю свой пользовательский ExceptionListener, я получаю от него ответ 404, а не Apache 404.
2) Наш хостинг-провайдер обновил наш производственный сервер с EasyApache 3 до EasyApache 4. Наряду с этим изменились некоторые из наших настроек конфигурации PHP. Мне нужно было, чтобы они снова включили SOAP и iconv в конфигурации PHP. Поскольку это работает безупречно на моем локальном хосте, я делаю вывод, что это ДОЛЖНО быть как-то связано с этим, но мне нужно будет точно определить точную проблему, чтобы они могли это исправить. Я подозреваю что-то в настройках.htaccess (RewriteMod), но я не знаю много об этом.
3) Есть сотни различных маршрутов, которые связаны с функциями контроллера, 90% из них доступны через AJAX POST. Все они работают отлично, кроме этого (который мы нашли до сих пор).
Функция контроллера:
/**
* @Route("/secured/helpdesk/save", name="saveTicket")
*/
public function saveTicketAction(Request $request = null)
{
$data = $request->request->all();
if (empty($data['message'])) return $this->createJsonResponse(array('error' => 'No Ticket Description or Message Provided', 'data' => $data));
...
The function is quite large, so I am not going to paste the whole thing, the error message above is what I receive along with the 403 response in PROD
}
Фронт-энд AJAX POST
function saveTicket()
{
$.ajax({
url: '{{ url("saveTicket") }}',
method: 'POST',
async: true,
data: $('#messageForm').serialize()
})
.done(function(data)
{
if (typeof(data.error) != 'undefined')
{
$('#errorMsg').html(data.error);
$('#pageError').modal('show');
}
else
{
$('#successMsg').html('Helpdesk Ticket Successfully Saved.');
$('#pageSuccess').modal('show');
window.location = '{{url('helpdeskAdmin')}}';
}
});
return false;
}
security.yml
security:
role_hierarchy:
ROLE_SUPERADMIN: ROLE_ACCOUNTADMIN
ROLE_ACCOUNTADMIN: ROLE_USER
providers:
main:
entity:
class: AppBundle\Entity\User
property: email
firewalls:
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: login
check_path: login
default_target_path: portalDashboard
require_previous_session: false
success_handler: authentication_handler
failure_handler: authentication_handler
logout:
path: /logout
target: /
http_basic:
realm: "Smarttrace Portal"
encoders:
AppBundle\Entity\User: sha512
access_control:
- { path: ^/superadmin, roles: ROLE_SUPERADMIN }
- { path: ^/accountadmin, roles: ROLE_ACCOUNTADMIN }
- { path: ^/secured, roles: ROLE_USER }
- { path: ^/payfast, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
routing.yml
app:
resource: "@AppBundle/Controller/"
type: annotation
logout:
path: /logout
1 ответ
Я понял, что эта проблема возникает только тогда, когда HTML (Rich-Text) отправляется в одном из параметров POST. Проблема действительно связана с EasyApache 4, где правила "ModSecurity" дают ложные срабатывания. Таким образом, 403 генерировался EasyApache 4 "ModSecurity" и, таким образом, запрещал параметры POST достигать Symfony.