CSRF Validation in AJAX With Symfony: Difference between revisions
(Created page with "Category:Symfony Category:PHP Category:jQuery Category:JavaScript Category:Web Development == Goal == From a Symfony page, submit POST data including a CS...") |
(No difference)
|
Revision as of 20:00, 10 February 2015
Goal
From a Symfony page, submit POST data including a CSRF token using jQuery, then validate that CSRF token in the controller that handles the request.
Template
csrf_token() is a built-in Twig template function with Symfony. Normally it's used with forms.
<div class="hidden" id="csrf-token" data-token="{{ csrf_token('') }}"><!-- --></div>
JavaScript/jQuery
- Bind an
ajaxSendhandler to the document that will pass along the csrf token in the request headers for every AJAX call.
$(document).bind('ajaxSend', function(elm, xhr, s){
if (s.type==="POST") {
var csrf_token = $(lclSettings.selectors.csrf).data('token');
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
}
});
Symfony controller
Retrieve the CSRF token from the request headers and validate it in the controller.[1][2]
<syntaxhighlight lang="php"> use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response;
// ...
/** * @Route("/update/completed/{id}", name="_updated_completed") * @ParamConverter("tutorial", class="AppBundle:Tutorial") * @Method("POST") */ public function updateCompletedAction(Request $request, Tutorial $tutorial) { // get the csrf token from the request header $csrf_token = $request->headers->get('x_csrf_token');
// get the object to validate the token $csrf = $this->get('form.csrf_provider');
// validation if ($csrf->isCsrfTokenValid(, $csrf_token)) {
// Handle the request and create a json string for the response } else { // Invalid token $response = new Response(json_encode(array( 'error' => 'Invalid request.' ))); }
// return JSON response $response->headers->set('Content-Type', 'application/json'); return $response; } </syntaxhighlighter>
- The
@ParamConverterannotation causes the id value to automatically be converted into an entity object, but it doesn't have any direct impact on the CSRF logic. - The
@Methodannotation causes only requests using the POST method to be matched. This also doesn't directly impact the CSRF, but it does provide a layer of protection from inspecting the requests. - Get the token string from the headers.
- Get a Symfony CSRF provider object to do the validation.
- Validate the token and only perform the action if the token is valid.
- Returns a JSON string to the script that called this action.
Notes
- ↑ How Can I Check Whether The Supplied CSRF Token Is Invalid In Symfony2, Stackoverflow
- ↑ Symfony CSRF and AJAX, Stackoverflow