Ограничить маршруты вызовом Ajax, это возможно в Symfony 2.6+?

Я ищу лучший способ добиться «автоматического» ограничения маршрутизации вызовов Ajax. Прямо сейчас я делаю следующее:

/**
 * @Secure(roles="IS_AUTHENTICATED_FULLY")
 * @Route("/someRoute", name="someRoute")
 * @Method("POST")
 */
public function eliminarFacturasAction(Request $request)
{
    $response['success'] = false;
    $status              = 400;

    if ($request->isXmlHttpRequest()) {
        // needs to set $response values and $status=200 all the time
    } else {
        // needs to handle the exception and return Json response
    }

    return new JsonResponse($response, $status ?: 200);
}

Чтобы избежать этого, могу ли я использовать это вместо этого?

 @Route("/someRoute", 
           name="routeName", 
           condition="request.headers.get('X-Requested-With') == 'XMLHttpRequest'"
 )

Я использую jQuery только как JS-фреймворк, поэтому XMLHttpRequest не будет проблемой. Какое исключение будет вызвано, если маршрут не будет выполнен через вызов Ajax? Могу ли я поймать его и показать сообщение пользователям? Или показать какую-то страницу 404?

Я нашел аналогичный вопрос здесь, но мне вообще непонятно


person ReynierPM    schedule 16.01.2015    source источник
comment
Есть ли веская причина ограничивать маршруты XmlHttpRequests? С точки зрения безопасности его можно обойти в любом случае.   -  person Gerry    schedule 16.01.2015
comment
хм ... я думаю, фильтры?   -  person David Fregoli    schedule 16.01.2015
comment
@Gerry, в моем случае да, всего несколько (может быть, 40 или больше) из-за требований, но сохраняю код, поскольку я зашумляю результаты, и я думаю, что это может быть плохой практикой, так как я участвую в DRY   -  person ReynierPM    schedule 16.01.2015
comment
@DavidFregoli Я никогда раньше не работал с фильтрами, а вы? Можете опубликовать пример, показывающий функциональность?   -  person ReynierPM    schedule 16.01.2015
comment
Я просто хотел указать, что вы нарушили бы спецификацию HTTP, вернув 404, если не запрашивали через ajax, и действительный ответ в противном случае.   -  person Gerry    schedule 16.01.2015
comment
@ Джерри, хорошо, как ты предложил мне справиться с этим?   -  person ReynierPM    schedule 16.01.2015
comment
Ну, лично я бы вообще не стал с этим справляться :), может быть, исключение отказа в доступе было бы более подходящим.   -  person Gerry    schedule 16.01.2015
comment
Вы можете проверить заголовок X-Requested-With в своем контроллере и, если он не найден, выдать ошибку 412. Если вы часто используете это, вы можете написать свою собственную аннотацию справиться с этим.   -  person Xatoo    schedule 16.01.2015
comment
@Xatoo это довольно сложно для меня, но я посмотрю на это, я не знаю, как подключить запрос к Resolver :-(   -  person ReynierPM    schedule 16.01.2015


Ответы (1)


Вы можете сделать это в прослушивателе kernel.request.

class DisallowNonXmlHttpRequestListener
{
    public function checkRequest(GetResponseEvent $event)
    {
        if (!$event->getRequest()->isXmlHttpRequest()) {
            throw new AccessDeniedHttpException();
        }
    }
}

И в конфигурации ваших служб:

services:
    disallow_non_xml_http_request_listener:
        class: DisallowNonXmlHttpRequestListener
        tags: [{ name: kernel.event_listener, event: kernel.request, method: checkRequest }]
person Gerry    schedule 16.01.2015
comment
И как я использую? Мне не ясно, запретит ли это все обычные запросы или нет. - person ReynierPM; 16.01.2015
comment
Да, это запрещает все запросы, отличные от ajax. - person Gerry; 16.01.2015
comment
У меня не работает Wil, так как мне не нужно запрещать все запросы на всем сайте, а только некоторые из них. - person ReynierPM; 16.01.2015
comment
Вы можете передать список маршрутов прослушивателю, а затем проверить, соответствует ли запрошенный маршрут. Тот же код, что и для прослушивателя входа в систему. - person Cerad; 16.01.2015
comment
@Cerad до сих пор не понимает сути, не могли бы вы опубликовать фрагмент кода, чтобы посмотреть, как это должно работать? Я немного потерялся в этот момент - person ReynierPM; 17.01.2015