Symfony: сделать токен CSRF доступным для всех шаблонов веток
В моем приложении есть запросы AJAX, и я хочу защитить их токенами CSRF. Однако вместо того, чтобы генерировать и передавать токен CSRF в средство визуализации Twig для использования в JavaScript, я бы хотел, чтобы токен CSRF был легко доступен на каждой html-странице, которую отображает Twig.
Я видел, что Laravel, кажется, поместил его в метатег, поэтому я могу легко получить его с помощью JavaScript. Но как это сделать в Symfony? Как я могу вставить этот токен на каждой странице?
Или это не очень хорошая практика?
2 ответа
Конечно, это хорошая практика!
У вас есть встроенная функция csrf_token('key')
в Symfony/ Twig для этого.
Пример:
<a href="{{ path('product_remove', {id: product.id, csrf: csrf_token('product') }) }}"
class="btn btn-info">Remove</a>
С контроллера, вы просто должны проверить это:
/**
* @Route("/product/remove/{csrf}/{id}", name="product_remove")
*/
public function removeProductAction($csrf, $id)
{
if ($csrf !== $this->get('security.csrf.token_manager')->getToken('product')->getValue()) {
throw new InvalidCsrfTokenException('Invalid CSRF token');
}
// delete $id
// cleans up url
return $this->redirectToRoute('product_list');
}
Ответ: вставьте его как глобальную переменную ветки и затем используйте Javascript, чтобы связать его со всеми запросами.
config.yml
twig:
## ...
globals:
csrfTokenManager: '@security.csrf.token_manager'
base.html.twig
<script>
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('x-csrf-token', '{{ csrfTokenManager.getToken('ajaxAuth') }}');
});
</script>
Получение контроллера
public function receiveAction (Request $request)
{
$tokenManager = $this->get('security.csrf.token_manager');
$tokenId = 'ajaxAuth';
$token = new CsrfToken($tokenId, $request->headers->get('x-csrf-token'));
if (!$tokenManager->isTokenValid($token)) {
throw new HttpException(403, 'Go away h4x0r');
}
}