Как обрабатывать запрос 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 - хорошее решение
- Первое, что нужно сделать, это ... отключить
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 работает как надо!