Как обрабатывать запрос Vue.js в Symfony как обычную отправку формы

Symfony предоставляет нам пакет symfony/form, который делает обработку отрисовки и отправки форм проще, чем когда-либо. Скоро это станет еще проще с новым помощником обработчика форм, но не в этом суть.

Когда я впервые начал работать с Vue.js, меня раздражало то, что мне очень хотелось сказать «до свидания» формам, отображаемым непосредственно в Twig (что очень удобно).

Я начал поиск пакетов «генераторов форм» для Vue.js. Их немного, но пока что не понравился ни один из них. В худшем случае я мог бы просто визуализировать форму каким-нибудь методом API, например /get-form-view, но это очень противоречит рабочему процессу / концепции Vue.js.

Итак ... Я начал спрашивать себя и думать:

«Как я могу отображать формы в Vue.js и обрабатывать их в Symfony? Хотя я могу прекратить рендеринг форм, как это делает Twig, я определенно хочу сохранить валидацию / обработку форм, предоставляемую Symfony »

Здесь есть несколько проблем, которые необходимо решить:

  • обработка токена csrf,
  • перестроение запроса « его структура должна быть такой же, как при отправке стандартной формы Symfony »,

Токен CSRF

Бэкэнд

По умолчанию для каждой формы, созданной с symfony/form пакетами, включена проверка токена CSRF. Это означает, что каждый запрос, предоставленный обработчику формы, должен содержать токен CSRF. Здесь есть несколько решений, я выберу 2, которые нашел для своего случая.

Плохой (если это только Ваш частный проект) - отключение проверки токена CSR

Каждый класс формы (это означает, что он происходит от Symfony\Component\Form\AbstractType) позволяет нам отключить проверку CSRF.

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

Отправка и обработка токена csrf с помощью вызова Vue.js - хорошее решение

  1. Первое, что нужно сделать, это ... отключить csrf_protection, как указано выше.

2. Теперь нам понадобится CsrfTokenValidatorService

3. Теперь проверка токена должна производиться в 2-х местах.

  • как я писал в другой статье (здесь), каждый запрос проходит через Authenticator, поэтому запрос должен быть проверен внутри него, так как это называется до того, как сработает KernelRequestEvent
  • KernelRequest::REQUEST

KernelRequestListener

Аутентификатор

4. Нам также нужен маршрут, по которому будет доставлен токен CSRF.

Внешний интерфейс

Теперь вместо того, чтобы добавлять getCsrf снова и снова в каждый вызов Axios, я написал свой собственный плагин для обработки почтового вызова с вызовом токена csrf рядом.

Плагин

Просто плагин делает 2 вещи:

  • вызывает бэкэнд: «Эй, дай мне токен CSRF- для этого UUID»,
  • затем делает второй вызов: «Привет, я получил этот CSRF для UUID, пожалуйста, проверьте его и пропустите»

Естественно, никто не говорит, что токен должен быть получен в момент выполнения вызова ajax, он также может быть получен в beforeMount, а затем предоставлен в форме, я просто не вижу причин для этого, поскольку мы все равно должны общаться с поддержкой токена.

Итак ... действительно ли это работает правильно, если мы предоставим фальшивый токен csrf? Да - я провел тест с жестко запрограммированным токеном в коде, и запрос был отклонен.

Не идеальное решение

Хотя это звучит не идеально, но работает примерно так же, как Symfony обрабатывает токены CSRF:

  • он использует form_name вместо UUID,
  • он генерирует новый токен при каждом запросе,

Восстановление запроса

Теперь, когда проверка токена CSRF заработала, наступает самое простое. Нам просто нужна логика, которая «возьмет запрос Axios - json» и преобразует его в правильные данные запроса, обычно используемые в Symfony.

И просто используйте это так:

Мои мысли по поводу этого решения

Единственная основная проблема, которую я здесь получил, это то, что getCsrf маршрут должен быть скрыт за аутентификацией, и только login должно быть разрешено передавать его без аутентификации, в противном случае после «поддельной формы» и скопированной внешней логики любой может легко получить токен CSRF.

Другой приятной защитой «на всякий случай» будет просто проверка того, откуда исходит запрос - если за пределами нашего домена, тогда - заблокировать его, таким образом, никто никогда не получит токен.

Помимо этого, просто потребовалось немного времени, чтобы понять, как сгенерировать токен CSRF, проверить его, обработать запрос и т.д. повторно применен.

И эй ... Проверка формы Symfony работает как надо!