2017-08-07 300 views
1

我期待将FOS Rest Bundle和FOS User Bundle结合到我的API应用程序中来注册新用户。问题是:API Rest“CSRF令牌无效,请尝试重新提交表单。”

  • 不能发现用户注册最佳做法API休息
  • 无法使用FOS用户注册类型注册用户,拿到400“的CSRF令牌无效请求无效,请尝试。重新提交表格。“

我该如何解决这些问题?

我的帖子正文

{ 
    "firstname": "xxx", 
    "lastname": "xxx", 
    "email":"[email protected]", 
    "username":"xxx", 
    "plainPassword":{ 
     "first":"xxx", 
     "second":"xxx" 
    } 
} 

响应

{ 
    "errors": [ 
     "The CSRF token is invalid. Please try to resubmit the form." 
    ], 
    "children": { 
     "email": {}, 
     "username": {}, 
     "plainPassword": { 
      "children": { 
       "first": {}, 
       "second": {} 
      } 
     }, 
     "firstname": {}, 
     "lastname": {} 
    } 
} 

用户类型表

class UserType extends AbstractType 
    { 
     /** 
     * @inheritDoc 
     */ 
     public function buildForm(FormBuilderInterface $builder, array $options) 
     { 
      $builder 
       ->add('firstname') 
       ->add('lastname'); 
     } 

     public function configureOptions(OptionsResolver $resolver) 
     { 
      $resolver->setDefaults([ 
       'crsf_protection' => false, 
       'csrf_token_id' => null, 
       'data_class' => 'TM\UserBundle\Document\User' 
      ]); 
     } 

     public function getParent() 
     { 
      return 'FOS\UserBundle\Form\Type\RegistrationFormType'; 

      // Or for Symfony < 2.8 
      // return 'fos_user_registration'; 
     } 
    } 

该控制器

class UserController extends FOSRestController 
{ 
    /** 
    * @Rest\Post("/register") 
    * @param Request $request 
    * @return null|Response 
    */ 
    public function postUserAction(Request $request) 
    { 
     /** @var $formFactory FormFactory */ 
     $formFactory = $this->get('form.factory'); 
     /** @var $userManager UserManagerInterface */ 
     $userManager = $this->get('fos_user.user_manager'); 
     /** @var $dispatcher EventDispatcherInterface */ 
     $dispatcher = $this->get('event_dispatcher'); 

     $user = $userManager->createUser(); 
     $user->setEnabled(true); 

     $event = new GetResponseUserEvent($user, $request); 
     $dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event); 

     if (null !== $event->getResponse()) { 
      return $event->getResponse(); 
     } 

     $form = $formFactory->create(UserType::class, $user); 

     $form->submit($request->request->all()); 

     if ($form->isValid()) { 
      $event = new FormEvent($form, $request); 
      $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event); 

      $userManager->updateUser($user); 

      if (null === $response = $event->getResponse()) { 
       $url = $this->generateUrl('fos_user_registration_confirmed'); 
       $response = new RedirectResponse($url); 
      } 

      $dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response)); 

      $view = $this->view(array('token' => $this->get("lexik_jwt_authentication.jwt_manager")->create($user)), Response::HTTP_CREATED); 

      return $this->handleView($view); 
     } 

     $view = $this->view($form, Response::HTTP_BAD_REQUEST); 
     return $this->handleView($view); 
    } 
} 

回答

1

因为你很可能需要全线禁用CSRF,特别是如果你的API通过形式直接处理数据的API(这我会建议你做的如何)。

你可以找到这个在这里一个聪明的解决方案:https://stackoverflow.com/a/9888593/4620798

你的具体情况,我想你可能需要删除csrf_token_id,因为它可能尽管你可以提交null值告诉表格反正禁用它?

另外,如果您将Angular2或任何其他“现代”前端框架用作消费者,您最终可能会遇到PREFLIGHT问题。如果/当你这样做时也有解决方案:)

相关问题