2017-06-08 16 views
13

repository with issueSymfony 3, पॉप्युलेट टोकन और ताज़ा उपयोगकर्ता

मैं ईमेल क्षेत्र के साथ इकाई उपयोगकर्ता के लिए एक रूप है:

->add('email', EmailType::class, [ 
       'constraints' => [ 
        new NotBlank(), 
        new Email([ 
         'checkMX' => true, 
        ]) 
       ], 
       'required' => true 
      ]) 

जब मैं ईमेल संपादन कर रहा हूँ कुछ करने के लिए [email protected] की तरह और फ़ॉर्म सबमिट यह मुझे पता चलता त्रुटि "यह मान मान्य ईमेल पता नहीं है।" कि ठीक है, लेकिन है कि सिम्फोनी के बाद टोकन में गलत ईमेल पॉप्युलेट और जब मैं किसी अन्य पृष्ठ पर जाकर कर रहा हूँ या सिर्फ फिर से लोड पृष्ठ, मैं इस हो रही है:

चेतावनी सुरक्षा प्रयोक्ता नाम चयनित में नहीं पाया जा सका उपयोगकर्ता प्रदाता।

मुझे लगता है कि सवाल यह है: क्यों सिम्फनी गलत ईमेल पॉप्युलेट करता है जो टोकन में सत्यापन विफल रहा और मैं इसे कैसे रोक सकता हूं?

नियंत्रक:

public function meSettingsAction(Request $request) 
    { 

     $user = $this->getUser(); 
     $userUnSubscribed = $this->getDoctrine()->getRepository('AppBundle:UserUnsubs')->findOneBy(
      [ 
       'email' => $user->getEmail(), 
      ] 
     ); 

     $form = $this->createForm(UserSettingsType::class, $user); 
     $form->get('subscribed')->setData(!(bool)$userUnSubscribed); 

     $form->handleRequest($request); 

     if ($form->isSubmitted() && $form->isValid()) { 
      /** 
      * @var $user User 
      */ 
      $user = $form->getData(); 

      /** @var UploadedFile $avatar */ 
      $avatar = $request->files->get('user_settings')['photo']; 

      $em = $this->getDoctrine()->getManager(); 

      if ($avatar) { 
       $avatar_content = file_get_contents($avatar->getRealPath()); 
       $avatarName = uniqid().'.jpg'; 
       $oldAvatar = $user->getPhoto(); 
       $user 
        ->setState(User::PHOTO_STATE_UNCHECKED) 
        ->setPhoto($avatarName); 
       $gearmanClient = $this->get('gearman.client'); 
       $gearmanClient->doBackgroundDependsOnEnv(
        'avatar_content_upload', 
        serialize(['content' => $avatar_content, 'avatarName' => $avatarName, 'oldAvatar' => $oldAvatar]) 
       ); 
      } 

      $subscribed = $form->get('subscribed')->getData(); 
      if ((bool)$userUnSubscribed && $subscribed) { 
       $em->remove($userUnSubscribed); 
      } elseif (!(bool)$userUnSubscribed && !$subscribed) { 
       $userUnSubscribed = new UserUnsubs(); 
       $userUnSubscribed->setEmail($form->get('email')->getData())->setTs(time()); 
       $em->persist($userUnSubscribed); 
      } 
      $user->setLastTs(time()); 
      $em = $this->getDoctrine()->getManager(); 
      $em->persist($user); 
      $em->flush(); 

      $this->get('user.manager')->refresh($user); 

      return $this->redirectToRoute('me'); 
     } 

     return $this->render(
      ':user:settings.html.twig', 
      [ 
       'form' => $form->createView(), 
      ] 
     ); 
    } 

युपीडी: यह ठीक काम करता है अगर मैं OAuthProvider में बदलने के लिए:

/** 
* @param \Symfony\Component\Security\Core\User\UserInterface $user 
* 
* @return \Symfony\Component\Security\Core\User\UserInterface 
*/ 
public function refreshUser(UserInterface $user) 
{ 
    return $this->loadUserByUsername($user->getName()); 
} 

रहे हैं:

/** 
* @param \Symfony\Component\Security\Core\User\UserInterface $user 
* 
* @return \Symfony\Component\Security\Core\User\UserInterface 
*/ 
public function refreshUser(UserInterface $user) 
{ 
    return $this->userManager($user->getId()); 
} 

लेकिन यह गंदा हैक हो रहा है ।

धन्यवाद।

+1

क्या आप अपना नियंत्रक दिखा सकते हैं? –

+0

@AlessandroMinoccheri मैंने प्रश्न के लिए नियंत्रक कोड जोड़ा है। – kRicha

+0

'रीफ्रेश यूज़र()' क्यों कहा जाता है कि ईमेल गलत है या नहीं? कृपया अपनी serurity.yml कॉन्फ़िगरेशन के बारे में कुछ और जानकारी जोड़ें। – lordrhodos

उत्तर

1

यह एक मुश्किल है, रिपोजिटरी के कारण समस्या को अलग करना आसान था। आप उपयोगकर्ता ऑब्जेक्ट को प्रमाणीकरण टोकन createForm() विधि में बाध्य कर रहे हैं।

$form->handleRequest($request) 

टोकन उपयोगकर्ता ऑब्जेक्ट से ईमेल को कॉल करने के बाद अपडेट किया गया है।

मैंने पहली बार इकाई में EquatableInterface.html को कार्यान्वित करके इसे हल करने के लिए सोचा था, लेकिन यह काम नहीं करता था, क्योंकि तुलना की गई वस्तु में पहले से ही गलत ईमेल पता सेट था।

यह भी EquatableInterface इंटरफ़ेस है, जो यदि उपयोगकर्ता वर्तमान उपयोगकर्ता के बराबर है की जाँच करने के लिए एक विधि को परिभाषित करता है लागू करने के लिए उपयोगी हो सकता है। इस इंटरफ़ेस को isEqualTo() विधि की आवश्यकता है।)

से मैं db से उपयोगकर्ता की एक बार पुनः लोड करने के लिए मजबूर कर और सुरक्षा टोकन को रीसेट करने के बारे में सोचा है, लेकिन यह मेरे दिमाग में आया था, कि यह सिर्फ डेटाबेस से वर्तमान उपयोगकर्ता ऑब्जेक्ट को ताज़ा करने के लिए पर्याप्त हो सकता है यदि फॉर्म विफल रहता है:

$this->get('doctrine')->getManager()->refresh($this->getUser());` 

आपके नियंत्रक में, यह आपकी समस्या का समाधान करेगा।

/** 
* @Route("/edit_me", name="edit") 
* @Security("has_role('ROLE_USER')") 
*/ 
public function editMyselfAction(Request $request) { 
    $form = $this->createForm(User::class, $this->getUser()); 

    if ($request->isMethod(Request::METHOD_POST)) { 
     $form->handleRequest($request); 
     if ($form->isSubmitted() && $form->isValid()) { 
      $user = $form->getData(); 
      $em = $this->getDoctrine()->getManager(); 
      $em->persist($user); 
      $em->flush(); 
     } else { 
      $this->get('doctrine')->getManager()->refresh($this->getUser()); 
     } 
    } 

    return $this->render(':security:edit.html.twig',['form' => $form->createView()]); 
} 

वैकल्पिक समाधान

issue at the Symfony repositoryAvoiding Entities in Forms और Decoupling Your Security User जो आपकी समस्या के समाधान के लिए एक अधिक जटिल दृष्टिकोण प्रदान करता है के बारे में कुछ मूल्यवान इनपुट में हुई।

+0

आपके ध्यान के लिए धन्यवाद, लेकिन यह गंदा हैक है: डी मैंने पहले से ही जिथब पर सिम्फनी/सिम्फनी रिपोजिटरी को एक मुद्दा पोस्ट कर दिया है और उन्हें मेरा भंडार प्रदान किया है। यह टोकन populating का सामान्य व्यवहार नहीं है। मेरे पास पहले से ही एक और गंदा हैक है, जिसे मेरे जवाब में वर्णित किया गया था। धन्यवाद फिर से) – kRicha

+0

अच्छा, ईमानदार होने के लिए मैं इसे एक गंदे हैक पर विचार नहीं करता लेकिन एक आवश्यक समाधान है क्योंकि आप $ उपयोगकर्ता को टोकन ऑब्जेक्ट से फॉर्म में कैसे बांधते हैं। यह व्यवहार की उम्मीद है। यदि आप इससे बचना चाहते हैं, तो आपको एक नया खाली उपयोगकर्ता ऑब्जेक्ट बनाना चाहिए, इसे वर्तमान में लॉग इन किए गए उपयोगकर्ता से आवश्यक डेटा के साथ प्रारंभ करें और इसे फ़ॉर्म में बाध्य करें। यदि फॉर्म मान्य है तो आप सबमिट किए गए उपयोगकर्ता ऑब्जेक्ट को मैन्युअल रूप से टोकन से उपयोगकर्ता ऑब्जेक्ट पर मैप करें। पूरी तरह से पूर्णता के लिए – lordrhodos

+0

। [मुद्दा जो आपने सिम्फनी रिपोजिटरी पर पोस्ट किया है] (https://github.com/symfony/symfony/issues/23215) को एसआरपी माना जाता है और एक बग नहीं है। तो यह आपके प्रश्न का एक वैध जवाब है। – lordrhodos

3

आपका उपयोगकर्ता टोकन फॉर्म द्वारा अपडेट किया गया प्रतीत होता है, भले ही ईमेल की बाधा फ्लश को रोकती है।

क्या आप जांच सकते हैं कि आपका फॉर्म isvalalid फ़ंक्शन से पहले है या नहीं? आप शायद किसी ईवेंट श्रोता या सत्यापनकर्ता से बचने का प्रयास कर सकते हैं।

किसी ईवेंट के साथ सबमिट करें, आपको ईमेल अखंडता की जांच करने में सक्षम होना चाहिए, और फिर refreshUser से बचने के लिए फॉर्मरर जोड़ें।

+0

क्या आपने उत्तर पोस्ट करने से पहले अपना प्रश्न पढ़ा था? – kRicha

+4

क्या आप गंभीर हैं? मैं समझता हूं कि आप अभी भी क्यों फंस गए हैं, हम यहां आपकी मदद करने के लिए स्वतंत्र हैं, कृपया विनम्र रहें। – fireaxe

+0

मैंने पहले से ही उल्लेख किया है कि फॉर्म जमा करने के बाद अद्यतन किया गया था, भले ही फॉर्म वैध नहीं है। जैसा कि आप कोड में देख सकते हैं: 'अगर ($ form-> सबमिट किया गया है() && $ form-> isValid()) {'वैधकर्ताओं की जांच कर रहा है, और यदि फॉर्म मान्य नहीं है तो इकाई में डेटा पॉप्युलेट नहीं कर रहा है। – kRicha

संबंधित मुद्दे