我希望将FOS Rest Bundle和FOS用户包结合到我的API应用程序中以注册新用户。问题是:
如何解决这些问题?
我的帖子
{
"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": {}
}
}
UserType表格
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);
}
}
答案 0 :(得分:1)
对于API,您可能需要全面禁用CSRF,特别是如果您的API直接通过表单处理数据(我建议您不管这样做)。
您可以在此处找到一个聪明的解决方案:https://stackoverflow.com/a/9888593/4620798
在您的特定情况下,我认为您可能需要删除csrf_token_id
,因为它可能会提交null
值,尽管您告诉表单无论如何都要禁用它?
另外,如果您使用Angular2或任何其他“现代”前端框架作为消费者,您可能最终会遇到PREFLIGHT问题。如果/当你这样做也有解决方案:)