Reputation: 165
I'm looking to combine FOS Rest Bundle AND FOS User Bundle to my API application to register new users. The problem is:
How can I resolve those issues?
My POST Body
{
"firstname": "xxx",
"lastname": "xxx",
"email":"[email protected]",
"username":"xxx",
"plainPassword":{
"first":"xxx",
"second":"xxx"
}
}
Response:
{
"errors": [
"The CSRF token is invalid. Please try to resubmit the form."
],
"children": {
"email": {},
"username": {},
"plainPassword": {
"children": {
"first": {},
"second": {}
}
},
"firstname": {},
"lastname": {}
}
}
UserType Form
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';
}
}
The Controller
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);
}
}
Upvotes: 2
Views: 2012
Reputation: 232
For an API you'll likely need to disable CSRF across the board, particularly if your API is processing data through forms directly (which I would recommend you do regardless).
You can find a clever solution for this here: https://stackoverflow.com/a/9888593/4620798
In your particular case, I think you may need to remove the csrf_token_id
as it may be submitting a null
value despite you telling the form to disable it anyway?
Separately, you'll probably end up running into PREFLIGHT issues if you're using Angular2 or any other "modern" frontend framework as the consumer. If/when you do there are solutions to that also :)
Upvotes: 1