php – Symfony2 – 重载注册表单导致CSRF错误(添加了github rep
我目前正在超载SonataUser注册表单,以便在人们创建帐户时我可以拥有自己的自定义表单.
我已经正确地重载了??所有东西(处理程序,表单类型,控制器和树枝模板).但是,当我发送表单时,我只返回数据并且不创建新用户.因此,我调查了一下,当我回应这个时,我发现了 var_dump($this->form->getErrors()); 我收到一条错误消息,说CSRF令牌无效.我正在使用Symfony 2.4.2和sonata用户2.2.x-dev. 我将向您展示我已经超载的所有类.目前,他们大多是从父母那里复制和粘贴的. 这是我的表单处理程序 <?php /* * This file is part of the Sonata package. * * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> * * For the full copyright and license information,please view the LICENSE * file that was distributed with this source code. * */ namespace ApplicationSonataUserBundleFormHandler; use SymfonyComponentFormForm; use SymfonyComponentHttpFoundationRequest; use FOSUserBundleModelUserInterface; use FOSUserBundleModelUserManagerInterface; use FOSUserBundleFormHandlerRegistrationFormHandler as BaseHandler; use SymfonyComponentFormFormInterface; use FOSUserBundleMailerMailerInterface; use FOSUserBundleUtilTokenGeneratorInterface; /** * * This file is an adapted version of FOS User Bundle RegistrationFormHandler class * * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/> */ class RegistrationFormHandler extends BaseHandler { protected $request; protected $userManager; protected $form; protected $mailer; protected $tokenGenerator; public function __construct(FormInterface $form,Request $request,UserManagerInterface $userManager,MailerInterface $mailer,TokenGeneratorInterface $tokenGenerator) { $this->form = $form; $this->request = $request; $this->userManager = $userManager; $this->mailer = $mailer; $this->tokenGenerator = $tokenGenerator; } /** * @param boolean $confirmation */ public function process($confirmation = false) { $user = $this->createUser(); $this->form->setData($user); if ('POST' === $this->request->getMethod()) { $this->form->bind($this->request); if ($this->form->isValid()) { var_dump('working !!'); $this->onSuccess($user,$confirmation); return true; } var_dump($this->form->getErrors()); } return false; } /** * @param boolean $confirmation */ protected function onSuccess(UserInterface $user,$confirmation) { if ($confirmation) { $user->setEnabled(false); if (null === $user->getConfirmationToken()) { $user->setConfirmationToken($this->tokenGenerator->generateToken()); } $this->mailer->sendConfirmationEmailMessage($user); } else { $user->setEnabled(true); } $this->userManager->updateUser($user); } /** * @return UserInterface */ protected function createUser() { return $this->userManager->createUser(); } } 这是我的表单类型: <?php /* * This file is part of the FOSUserBundle package. * * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/> * * For the full copyright and license information,please view the LICENSE * file that was distributed with this source code. */ namespace ApplicationSonataUserBundleFormType; use EntitiesUser; use SymfonyComponentFormAbstractType; use SymfonyComponentFormFormBuilderInterface; use SymfonyComponentOptionsResolverOptionsResolverInterface; use SonataUserBundleModelUserInterface; class RegistrationFormType extends AbstractType { private $class; /** * @var array */ protected $mergeOptions; /** * @param string $class The User class name * @param array $mergeOptions Add options to elements */ public function __construct($class,array $mergeOptions = array()) { $this->class = $class; $this->mergeOptions = $mergeOptions; } public function buildForm(FormBuilderInterface $builder,array $options) { $builder ->add('username',null,array_merge(array( 'label' => 'form.username','translation_domain' => 'SonataUserBundle',),$this->mergeOptions)) ->add('email','email',array_merge(array( 'label' => 'form.email',$this->mergeOptions)) ->add('plainPassword','repeated',array_merge(array( 'type' => 'password','required' => true,'options' => array('translation_domain' => 'SonataUserBundle'),'first_options' => array_merge(array( 'label' => 'form.password',$this->mergeOptions),'second_options' => array_merge(array( 'label' => 'form.password_confirmation','invalid_message' => 'fos_user.password.mismatch',$this->mergeOptions)) ->add('lastName',array_merge(array( 'label' => 'form.label_lastname',$this->mergeOptions)) ->add('firstName',array_merge(array( 'label' => 'form.label_firstname',$this->mergeOptions)) ->add('date_of_birth','birthday',array_merge(array( 'label' => 'form.label_date_of_birth',$this->mergeOptions)) ->add('gender','sonata_user_gender',array( 'label' => 'form.label_gender','choices' => array( UserInterface::GENDER_FEMALE => 'gender_female',UserInterface::GENDER_MALE => 'gender_male',) )) ->add('phone',array_merge(array( 'label' => 'form.label_phone',$this->mergeOptions)) ->add('address',array_merge(array( 'label' => 'form.address',$this->mergeOptions)) ->add('city',array_merge(array( 'label' => 'form.city',$this->mergeOptions)) ->add('state','choice',array_merge(array( 'label' => 'form.state','multiple' => false,'expanded' => false ),$this->mergeOptions)) ->add('country',array_merge(array( 'label' => 'form.country',$this->mergeOptions)) ->add('postalCode',array_merge(array( 'label' => 'form.postalCode',$this->mergeOptions)) // ->add('children','collection',array_merge(array( // 'type' => new ChildFormType('ApplicationSonataUserBundleEntityUser'),// 'translation_domain' => 'SonataUserBundle',// 'allow_add' => true,// 'allow_delete' => true,// 'by_reference' => false,// ),$this->mergeOptions)) ; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => $this->class,'intention' => 'registration',)); } public function getName() { return 'sonata_user_registration'; } } 这是我的注册控制器 <?php /* * This file is part of the Sonata package. * * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> * * For the full copyright and license information,please view the LICENSE * file that was distributed with this source code. */ namespace ApplicationSonataUserBundleController; use SymfonyComponentDependencyInjectionContainerAware; use SymfonyComponentHttpFoundationRequest; use SymfonyComponentHttpFoundationResponse; use SymfonyComponentHttpFoundationRedirectResponse; use SymfonyComponentHttpKernelExceptionNotFoundHttpException; use SymfonyComponentSecurityCoreExceptionAccessDeniedException; use SymfonyComponentSecurityCoreExceptionAccountStatusException; use FOSUserBundleModelUserInterface; /** * Class SonataRegistrationController * * This class is inspired from the FOS RegistrationController * * @package SonataUserBundleController * * @author Hugo Briand <briand@ekino.com> */ class RegistrationFOSUser1Controller extends ContainerAware { public function registerAction() { $user = $this->container->get('security.context')->getToken()->getUser(); if ($user instanceof UserInterface && 'POST' === $this->container->get('request')->getMethod()) { $this->container->get('session')->getFlashBag()->set('sonata_user_error','sonata_user_already_authenticated'); $url = $this->container->get('router')->generate('sonata_user_profile_show'); return new RedirectResponse($url); } $form = $this->container->get('sonata.user.registration.form'); $formHandler = $this->container->get('sonata.user.registration.form.handler'); $confirmationEnabled = $this->container->getParameter('fos_user.registration.confirmation.enabled'); $process = $formHandler->process($confirmationEnabled); var_dump(0); if ($process) { var_dump(1); exit(); $user = $form->getData(); $authUser = false; if ($confirmationEnabled) { $this->container->get('session')->set('fos_user_send_confirmation_email/email',$user->getEmail()); $route = 'fos_user_registration_check_email'; } else { $authUser = true; $route = $this->container->get('session')->get('sonata_basket_delivery_redirect','sonata_user_profile_show'); $this->container->get('session')->remove('sonata_basket_delivery_redirect'); } $this->setFlash('fos_user_success','registration.flash.user_created'); $url = $this->container->get('session')->get('sonata_user_redirect_url'); if (null === $url || "" === $url) { $url = $this->container->get('router')->generate($route); } $response = new RedirectResponse($url); if ($authUser) { $this->authenticateUser($user,$response); } return $response; } $this->container->get('session')->set('sonata_user_redirect_url',$this->container->get('request')->headers->get('referer')); return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(),array( 'form' => $form->createView(),)); } /** * Tell the user to check his email provider */ public function checkEmailAction() { $email = $this->container->get('session')->get('fos_user_send_confirmation_email/email'); $this->container->get('session')->remove('fos_user_send_confirmation_email/email'); $user = $this->container->get('fos_user.user_manager')->findUserByEmail($email); if (null === $user) { throw new NotFoundHttpException(sprintf('The user with email "%s" does not exist',$email)); } return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:checkEmail.html.'.$this->getEngine(),array( 'user' => $user,)); } /** * Receive the confirmation token from user email provider,login the user */ public function confirmAction($token) { $user = $this->container->get('fos_user.user_manager')->findUserByConfirmationToken($token); if (null === $user) { throw new NotFoundHttpException(sprintf('The user with confirmation token "%s" does not exist',$token)); } $user->setConfirmationToken(null); $user->setEnabled(true); $user->setLastLogin(new DateTime()); $this->container->get('fos_user.user_manager')->updateUser($user); if ($redirectRoute = $this->container->getParameter('sonata.user.register.confirm.redirect_route')) { $response = new RedirectResponse($this->container->get('router')->generate($redirectRoute,$this->container->getParameter('sonata.user.register.confirm.redirect_route_params'))); } else { $response = new RedirectResponse($this->container->get('router')->generate('fos_user_registration_confirmed')); } $this->authenticateUser($user,$response); return $response; } /** * Tell the user his account is now confirmed */ public function confirmedAction() { $user = $this->container->get('security.context')->getToken()->getUser(); if (!is_object($user) || !$user instanceof UserInterface) { throw new AccessDeniedException('This user does not have access to this section.'); } return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:confirmed.html.'.$this->getEngine(),)); } /** * Authenticate a user with Symfony Security * * @param FOSUserBundleModelUserInterface $user * @param SymfonyComponentHttpFoundationResponse $response */ protected function authenticateUser(UserInterface $user,Response $response) { try { $this->container->get('fos_user.security.login_manager')->loginUser( $this->container->getParameter('fos_user.firewall_name'),$user,$response); } catch (AccountStatusException $ex) { // We simply do not authenticate users which do not pass the user // checker (not enabled,expired,etc.). } } /** * @param string $action * @param string $value */ protected function setFlash($action,$value) { $this->container->get('session')->getFlashBag()->set($action,$value); } protected function getEngine() { return $this->container->getParameter('fos_user.template.engine'); } } 这是我的服务: sonata.user.registration.form.type: class: ApplicationSonataUserBundleFormTypeRegistrationFormType arguments: [ "%fos_user.model.user.class%"] tags: - { name: form.type,alias: sonata_user_registration } sonata.child.registration.form.type: class: ApplicationSonataUserBundleFormTypeChildFormType arguments: [ "%fos_user.model.user.class%"] tags: - { name: form.type,alias: sonata_child_registration } sonata.user.registration.form.handler.default: class: ApplicationSonataUserBundleFormHandlerRegistrationFormHandler scope: request public: false arguments: [@fos_user.registration.form,@request,@fos_user.user_manager,@fos_user.mailer,@fos_user.util.token_generator] 这是我的奏鸣曲用户配置(app / config / config.yml) sonata_user: security_acl: false manager_type: orm # Can be orm for mongodb table: user_group: "my_custom_user_group_association_table_name" impersonating: route: page_slug parameters: { path: / } class: # Entity Classes user: ApplicationSonataUserBundleEntityUser group: ApplicationSonataUserBundleEntityGroup admin: # Admin Classes user: class: SonataUserBundleAdminEntityUserAdmin controller: SonataAdminBundle:CRUD translation: SonataUserBundle group: class: SonataUserBundleAdminEntityGroupAdmin controller: SonataAdminBundle:CRUD translation: SonataUserBundle profile: # Profile Form (firstname,lastname,etc ...) form: type: sonata_user_profile handler: sonata.user.profile.form.handler.default name: sonata_user_profile_form validation_groups: [Profile] register: # You may customize the registration forms over here form: type: sonata_user_registration handler: sonata.user.registration.form.handler.default name: sonata_user_registration_form validation_groups: # Defaults: - Registration - Default 我的树枝渲染: {% block fos_user_content %} <br> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="well"> <div class="panel-heading"> <h3>{{ 'title_user_registration'|trans({},'SonataUserBundle') }}</h3> </div> <div class="panel-body"> <form ng-app="userRegistrationApp" action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST" class="fos_user_registration_register form-horizontal"> <h4>{{ 'General'|trans({},'SonataUserBundle') }}</h4> <hr> <div class="form-group"> {{ form_label(form.username,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.username,{'attr': {'class': 'form-control'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.email,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.email,{'attr': {'class': 'form-control'}}) }} </div> </div> <br> <h4>{{ 'form.label_plain_password'|trans({},'SonataUserBundle') }}</h4> <hr> <div class="form-group"> {{ form_label(form.plainPassword.first,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.plainPassword.first,{'attr': {'class': 'form-control'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.plainPassword.second,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.plainPassword.second,{'attr': {'class': 'form-control'}}) }} </div> </div> <br> <h4>{{ 'Profile'|trans({},'SonataUserBundle') }}</h4> <hr> <div class="form-group"> {{ form_label(form.lastName,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.lastName,{'attr': {'class': 'form-control'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.firstName,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.firstName,{'attr': {'class': 'form-control'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.date_of_birth,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.date_of_birth,{'attr': {'class': '' }}) }} </div> </div> <div class="form-group"> {{ form_label(form.gender,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.gender,{'attr': {'class': ''}}) }} </div> </div> <div class="form-group"> {{ form_label(form.phone,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.phone,{'attr': {'class': 'form-control bfh-phone','data-country':'sonata_user_registration_form_country'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.address,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.address,{'attr': {'class': 'form-control'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.city,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.city,{'attr': {'class': 'form-control'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.country,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.country,{'attr': {'class': 'form-control bfh-countries',' data-country':'US'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.state,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.state,{'attr': {'class': 'form-control bfh-states','data-country':'sonata_user_registration_form_country'}}) }} </div> </div> <div class="form-group"> {{ form_label(form.postalCode,{'label_attr': {'class': 'col-xs-4 control-label'}}) }} <div class="col-xs-8"> {{ form_widget(form.postalCode,{'attr': {'class': 'form-control'}}) }} </div> </div> <br> {{ form_rest(form) }} {#<a href="#Children" class="btn btn-link" ng-click="userRegistrationService.addEmptyChild()"><span class="glyphicon glyphicon-plus-sign"></span> {{ 'AddAChildren'|trans({},'SonataUserBundle') }}</a>#} <div class="form-actions"> <button type="submit" class="btn btn-success pull-right">{{ 'registration.submit'|trans({},'FOSUserBundle') }}</button> </div> </form> </div> </div> </div> </div> {% endblock fos_user_content %} 我真的不知道为什么我得到错误: array (size=1) 0 => object(SymfonyComponentFormFormError)[1125] private 'message' => string 'Le jeton CSRF est invalide. Veuillez renvoyer le formulaire.' (length=60) protected 'messageTemplate' => string 'Le jeton CSRF est invalide. Veuillez renvoyer le formulaire.' (length=60) protected 'messageParameters' => array (size=0) empty protected 'messagePluralization' => null 因为我在我的页面{{form_rest(form)}}中存在令牌字段… 更新我创建了一个github存储库,以便可以拉出我的配置,以便您可以自己查看问题. https://github.com/ima-tech/testSonataUser 解决方法
好吧,当我克隆你的github repo时,我能够通过调整你的服务来消除CSRF错误.
parameters: # osc_default.example.class: OSCDefaultBundleExample services: # osc_default.example: # class: %osc_default.example.class% # arguments: [@service_id,"plain_value",%parameter%] sonata.user.registration.form.type: class: ApplicationSonataUserBundleFormTypeRegistrationFormType arguments: [ "%fos_user.model.user.class%"] tags: - { name: form.type,alias: sonata_user_registration } sonata.child.registration.form.type: class: ApplicationSonataUserBundleFormTypeChildFormType arguments: [ "%fos_user.model.user.class%"] tags: - { name: form.type,alias: sonata_child_registration } sonata.user.registration.form.handler.default: class: ApplicationSonataUserBundleFormHandlerRegistrationFormHandler scope: request public: false arguments: [@sonata.user.registration.form,@sonata.user.user_manager,@fos_user.util.token_generator] 你看,在sonata.user.registration.form.handler.default:在参数中,你需要设置@ sonata.user.registration.form和@ sonata.user.user_manager而不是@ fos_user.registration.form和@fos_user .user_manager (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |