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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?