【问题标题】:API Rest "The CSRF token is invalid. Please try to resubmit the form."API Rest "CSRF 令牌无效。请尝试重新提交表单。"
【发布时间】:2018-01-15 01:36:29
【问题描述】:

我希望将 FOS Rest Bundle 和 FOS User Bundle 结合到我的 API 应用程序中以注册新用户。问题是:

  • 在 API Rest 上找不到用户注册的最佳做法
  • 无法使用 fos 用户注册类型注册用户,收到 400 Bad Request 并显示“CSRF 令牌无效。请尝试重新提交表单。”

我该如何解决这些问题?

我的帖子正文

{
    "firstname": "xxx",
    "lastname": "xxx",
    "email":"xxxxx@xxxx.com",
    "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);
    }
}

【问题讨论】:

    标签: rest symfony fosuserbundle fosrestbundle


    【解决方案1】:

    对于 API,您可能需要全面禁用 CSRF,尤其是当您的 API 直接通过表单处理数据时(我建议您无论如何都这样做)。

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

    在您的特定情况下,我认为您可能需要删除 csrf_token_id,因为它可能会提交 null 值,尽管您告诉表单无论如何都要禁用它?

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

    【讨论】:

      猜你喜欢
      • 2014-06-20
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2017-08-01
      • 2015-04-28
      • 2012-12-15
      • 2020-07-18
      相关资源
      最近更新 更多