doujing6053
2018-11-03 11:55
浏览 44
已采纳

Symfony 4 Validator - 如果无效则自动注销

I wanted to validate my User Object ($user) with the Symfony Validator and return a JsonResponse ($response) if the form input data is valid / is not valid. But I have the issue that I get logged out automatically when the data could not be validated. I have to login again and this is not the behaviour I expect when some data ist not valid. I found a workaround (see comments below) but this is not very satisfying :/

Here is the method of my Controller:

 /**
 * Update user profile data
 *
 * @Route("/api/users/updateprofile")
 * @Security("is_granted('USERS_LIST')")
 */

public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
{
    $request = Request::createFromGlobals();
    // Prepare Response
    $response = new JsonResponse();
    $response->setData([]);
    /** @var User $user */
    $user = $this->getUser();
    $oldName = $user->getName();
    $oldEmail = $user->getEmail();

    $user->setName($request->request->get('name'));
    $user->setEmail($request->request->get('email'));

    $errors = $validator->validate($user);
    if (count($errors) > 0) { // if this -> auto logout
        $user->setName($oldName); // if I set the both attributes back to the old value
        $user->setEmail($oldEmail); // then I don't get logged out automatically but this is just a workaround and not satisfying
        $entityManager = $this->getDoctrine()->getManager(); // forgot to remove this
        $entityManager->persist($user); // and this line, this is actually deleted in the real code

        foreach ($errors as $error) {
            $errorMessage = $error->getMessage();
            $errorField = $error->getPropertyPath();
            $flashMessageBuilder->addErrorMessage($errorMessage, $errorField);
        };

        return $response;
    }

    $entityManager = $this->getDoctrine()->getManager();
    $entityManager->persist($user);
    $entityManager->flush();

    $flashMessageBuilder->addSuccessMessage("Success!");
    return $response;
}

Sorry for my bad english and thank you in advance!

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • doudou1897 2018-11-03 12:54
    已采纳

    You are persisting the User Object even if there are errors in validation, which can cause the problem with the logout.

    Try to update ONLY in case there is no validation error:

    public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
    {
        $request = Request::createFromGlobals();
    
        // Prepare Response
        $response = new JsonResponse();
        $response->setData([]);
    
        /** @var User $user */
        $user = $this->getUser();
    
        $user->setName($request->request->get('name'));
        $user->setEmail($request->request->get('email'));
    
        $errors = $validator->validate($user);
        if (count($errors) == 0) {
            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();
    
            $flashMessageBuilder->addSuccessMessage("Success!");
            return $response;
        }
    
        foreach ($errors as $error) {
            $errorMessage = $error->getMessage();
            $errorField = $error->getPropertyPath();
            $flashMessageBuilder->addErrorMessage($errorMessage, $errorField);
        };
    
        return $response;
    }
    

    But I think you should not mix API calls and the classical form approach utilizing FlashMessages, instead return a proper JSON result.

    So consider to change the code accordingly:

    public function apiProfileUpdate(ValidatorInterface $validator, FlashMessageBuilder $flashMessageBuilder)
    {
        $request = Request::createFromGlobals();
    
        /** @var User $user */
        $user = $this->getUser();
    
        $user->setName($request->request->get('name'));
        $user->setEmail($request->request->get('email'));
    
        $errors = $validator->validate($user);
        if (count($errors) == 0) {
            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();
    
            return new JsonResponse(['success' => true]);
        }
    
        $data = [];
        foreach ($errors as $error) {
            $data[$error->getPropertyPath()] = $error->getMessage();
        };
    
        return new JsonResponse(['success' => false, 'errors' => $data], 400);
    }
    

    Now your calling code can handle a 200 result (success) and the error case with status code 400 and display the error messages for all failed fields from the errors part in the result body.

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题