php - Generate CSRF token dependig on datetime -
exists way in symfony 2 generate csrf token @ each rendering of form? in controller tried this:
$request = $this->get('request'); if ($request->getmethod() != 'post') { $csrf = $this->get('form.csrf_provider'); $date= new \datetime("now"); $this->date = $date->format('y-m-d h:i:s'); $token = $csrf->generatecsrftoken($this->date); } elseif($request->getmethod() == "post") { $csrf = $this->get('form.csrf_provider'); $token = $csrf->generatecsrftoken($this->date); } $form = $this->createformbuilder() .... ->add('_token','hidden',array( 'data' => $token ))->getform(); if ($request->getmethod() == 'post') { $form->bindrequest($request); if ($form->isvalid()) { } }
all time in request right token hash. after bindrequest change default hash generated security string in parameters.ini , isvalid method returns false response. exists way, how adjust it?
edit in response theunraveler answer, edited controller , create csrf provider, still im geting "the csrf token invalid. please try resubmit form" error. csrf provider looks this:
namespace my\namespace; use symfony\component\httpfoundation\session; use symfony\component\form\extension\csrf\csrfprovider\csrfproviderinterface; class mycsrfprovider implements csrfproviderinterface { protected $session; protected $secret; protected $datetime; public function __construct(session $session, $secret) { $this->secret = $secret; $this->datetime = new \datetime('now'); $this->session = $session; } public function generatecsrftoken($intention) { return sha1($this->secret.$intention.$this->datetime->format('ymdhis').$this->getsessionid()); } public function iscsrftokenvalid($intention, $token) { return $token === $this->generatecsrftoken($intention); } protected function getsessionid() { return $this->session->getid(); } }
than add config.yml service class:
services: form.csrf_provider: class: my\namespace\mycsrfprovider arguments: [ @session, %kernel.secret% ]
and controller change this:
//any form without _token field $form = $this->createformbuilder() ->add('field1') ->add('field2')->getform() if ($this->getrequest()->getmethod() == 'post') { $request = $this->getrequest(); $form->bindrequest($request); if ($form->isvalid()) { return $this->redirect($this->generateurl('somewhere')); } }
cant problem in seconds in hash? becouse if remove seconds datetime format, works, 1 min expiration , not solution. think, reason is, time changed.
symfony's form
component generates csrf token in form event. see class symfony\component\form\extension\csrf\eventlistener\csrfvalidationlistener
on how existing implementation works. means when call bindrequest()
(or bind()
in symfony 2.2+) on form, form event gets called , overwrites token declared.
the correct way define different token create csrfprovider
, class write implements symfony\component\form\extension\csrf\csrfprovider\csrfproviderinterface
. check out symfony\component\form\extension\csrf\csrfprovider\defaultcsrfprovider example of how implement this.
once write class, in app/config/parameters.yml
(or config file, doesn't matter where), set form.csrf_provider.class
parameter name of class.
after of that, should able remove of custom code wrote controller, , use form system though nothing different (i.e., remove ->add('_token')...
parts).
hope helps!
Comments
Post a Comment