2012-11-06 14 views
8

मैं OWuth के साथ उपयोगकर्ता लॉगिन करने के लिए HWIOAuthBundle का उपयोग कर रहा हूं, मैंने एक कस्टम उपयोगकर्ता प्रदाता बनाया है जो उपयोगकर्ता के अस्तित्व में नहीं है:Symfony2: कुछ फ़ील्ड गुम होने पर उपयोगकर्ताओं को पंजीकरण के बाद पूर्ण पंजीकरण करें

public function loadUserByOAuthUserResponse(UserResponseInterface $response) 
{ 
    $attr = $response->getResponse(); 
    switch($response->getResourceOwner()->getName()) { 
     case 'google': 
      if(!$user = $this->userRepository->findOneByGoogleId($attr['id'])) { 
       if(($user = $this->userRepository->findOneByEmail($attr['email'])) && $attr['verified_email']) { 
        $user->setGoogleId($attr['id']); 
        if(!$user->getFirstname()) { 
         $user->setFirstname($attr['given_name']); 
        } 
        if(!$user->getLastname()) { 
         $user->setLastname($attr['family_name']); 
        } 
        $user->setGoogleName($attr['name']); 
       }else{ 
        $user = new User(); 
        $user->setUsername($this->userRepository->createUsernameByEmail($attr['email'])); 
        $user->setEmail($attr['email']); 
        $user->setFirstname($attr['given_name']); 
        $user->setLastname($attr['family_name']); 
        $user->setPassword(''); 
        $user->setIsActive(true); 
        $user->setGoogleId($attr['id']); 
        $user->setGoogleName($attr['name']); 
        $user->addGroup($this->groupRepository->findOneByRole('ROLE_USER')); 
        $this->entityManager->persist($user); 
       } 
      } 
      break; 
     case 'facebook': 
      if(!$user = $this->userRepository->findOneByFacebookId($attr['id'])) { 
       if(($user = $this->userRepository->findOneByEmail($attr['email'])) && $attr['verified']) { 
        $user->setFacebookId($attr['id']); 
        if(!$user->getFirstname()) { 
         $user->setFirstname($attr['first_name']); 
        } 
        if(!$user->getLastname()) { 
         $user->setLastname($attr['last_name']); 
        } 
        $user->setFacebookUsername($attr['username']); 
       }else{ 
        $user = new User(); 
        $user->setUsername($this->userRepository->createUsernameByEmail($attr['email'])); 
        $user->setEmail($attr['email']); 
        $user->setFirstname($attr['first_name']); 
        $user->setLastname($attr['last_name']); 
        $user->setPassword(''); 
        $user->setIsActive(true); 
        $user->setFacebookId($attr['id']); 
        $user->setFacebookUsername($attr['username']); 
        $user->addGroup($this->groupRepository->findOneByRole('ROLE_USER')); 
        $this->entityManager->persist($user); 
       } 
      } 
      break; 
    } 

    $this->entityManager->flush(); 


    if (null === $user) { 
     throw new AccountNotLinkedException(sprintf("User '%s' not found.", $attr['email'])); 
    } 

    return $user; 
} 

समस्या यह है कि उदाहरण के लिए ट्विटर ईमेल नहीं देता है या मैं कुछ नए फ़ील्ड बनने से पहले कुछ अतिरिक्त फ़ील्ड शामिल करना चाहता हूं। क्या उपयोगकर्ता को इसे बनाने से पहले "पूर्ण पंजीकरण" फ़ॉर्म पर रीडायरेक्ट करने का कोई तरीका है?

मैंने एक अनुरोध श्रोता जोड़ने की कोशिश की है, कि प्रत्येक अनुरोध पर, यदि उपयोगकर्ता लॉग है, तो जांचता है कि ईमेल वहां है और यदि यह पूर्ण_ पंजीकरण पृष्ठ पर रीडायरेक्ट नहीं करता है, लेकिन यह भी रीडायरेक्ट करेगा उपयोगकर्ता होमपेज पर जाता है, लॉगआउट या कुछ और करने के लिए, मैं उसे केवल तभी रीडायरेक्ट करना चाहता हूं यदि वह कुछ उपयोगकर्ता प्रतिबंधित पृष्ठों तक पहुंचने का प्रयास करता है।

या बेहतर, इसे तब तक न बनाएं जब तक कि वह सभी आवश्यक सूचनाएं न दे।

+0

@ एलनूर आपने क्या संपादित किया? सिर्फ यह जानने के लिए कि क्या कुछ गलत था – alex88

+0

अंतिम संपादन टाइमस्टैम्प पर क्लिक करें और अपने लिए देखें। –

+0

आज क्या अशिष्ट जवाब है, बुरा मूड आज? – alex88

उत्तर

6

मैं अपने आप को द्वारा समाधान मिल गया है, मैं मैन्युअल रूप से कोई नया अपवाद बना लिया है कस्टम Oauth उपयोगकर्ता प्रदाता जब मैं जांचता हूं कि कोई उपयोगकर्ता मौजूद है या मैं एक नया उपयोगकर्ता बना रहा हूं तो मैं जांचता हूं कि आवश्यक फ़ील्ड गुम हैं या नहीं:

if (!$user->getEmail()) { 
    $e = new IncompleteUserException("Your account doesn't has a mail set"); 
    $e->setUser($user); 
    throw $e; 
} 

उस मामले में उपयोगकर्ता सत्र में है कि अपवाद के साथ, लॉगिन प्रपत्र पर पुनः निर्देशित किया जाएगा, तो प्रवेश पृष्ठ में मुझे क्या करना: अपवाद में $ उपयोगकर्ता के साथ

if($error instanceof IncompleteUserException) { 
    $session->set(SecurityContext::AUTHENTICATION_ERROR, $error); 
    return $this->redirect($this->generateUrl('register_complete')); 
} 

और यह पुनः निर्देशित किया जाएगा एक फार्म के लिए इसलिए यह केवल लापता जानकारी के लिए पूछ सकता है और फिर उपयोगकर्ता को लॉगिन कर सकता है।

+1

** यह समाधान बहुत ही सुरुचिपूर्ण ** नहीं है, लेकिन काम करना चाहिए। – mate64

1

मैं एक एसएफ साइट पर माइग्रेट करते समय एक समान समस्या में भाग गया। माइग्रेशन के बाद मैं चाहता था कि माइग्रेटेड उपयोगकर्ता अपनी प्रोफाइल पूरी करें, जबकि नए पंजीकृत उपयोगकर्ता तुरंत शुरू हो सकते हैं।

मैंने इसे एक अनुरोध पत्रक का उपयोग करके अपने विचार के समान हल किया लेकिन पृष्ठों की श्वेतसूची को जोड़ा जो उपयोगकर्ता को अपनी प्रोफ़ाइल के पूरा होने के बिना अनुमति है। उन पृष्ठों की संख्या के आधार पर, जिन्हें आप चाहते हैं कि उपयोगकर्ता को अपनी प्रोफ़ाइल के पूरा होने तक पहुंच प्राप्त हो, आप ब्लैकलिस्ट का उपयोग करने पर भी विचार कर सकते हैं।

मैंने प्रोफ़ाइल समापन पृष्ठ पर पुनर्निर्देशित करने के लिए किसी विशेष फ़ील्ड के अस्तित्व की जांच नहीं की, लेकिन उपयोगकर्ता डेटाबेस को माइग्रेट करते समय "ROLE_MIGRATION" भूमिका निभाई। अपने मामले में आप oauth के माध्यम से उपयोगकर्ता बनाते समय भूमिका जोड़ सकते हैं।

यहाँ मेरे अनुरोध श्रोता का कोड: में

<?php 

namespace Acme\UserBundle\Exception; 

use Symfony\Component\Security\Core\Exception\AuthenticationException; 
use HWI\Bundle\OAuthBundle\Security\Core\Exception\OAuthAwareExceptionInterface; 

/** 
* IncompleteUserException is thrown when the user isn't fully registered (e.g.: missing some informations). 
* 
* @author Alessandro Tagliapietra http://www.alexnetwork.it/ 
*/ 
class IncompleteUserException extends AuthenticationException implements OAuthAwareExceptionInterface 
{ 
    private $user; 
    private $accessToken; 
    private $resourceOwnerName; 

    /** 
    * {@inheritdoc} 
    */ 
    public function setAccessToken($accessToken) 
    { 
     $this->accessToken = $accessToken; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getAccessToken() 
    { 
     return $this->accessToken; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getResourceOwnerName() 
    { 
     return $this->resourceOwnerName; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function setResourceOwnerName($resourceOwnerName) 
    { 
     $this->resourceOwnerName = $resourceOwnerName; 
    } 

    public function setUser($user) 
    { 
     $this->user = $user; 
    } 

    public function getUser($user) 
    { 
     return $this->user; 
    } 

    public function serialize() 
    { 
     return serialize(array(
      $this->user, 
      $this->accessToken, 
      $this->resourceOwnerName, 
      parent::serialize(), 
     )); 
    } 

    public function unserialize($str) 
    { 
     list(
      $this->user, 
      $this->accessToken, 
      $this->resourceOwnerName, 
      $parentData 
     ) = unserialize($str); 
     parent::unserialize($parentData); 
    } 
} 

इस तरह,:

public function onRequest(GetResponseEvent $evt) 
{ 

    if (HttpKernelInterface::MASTER_REQUEST !== $evt->getRequestType()) 
    { 
     return; 
    } 

    $token = $this->securityContext->getToken(); 

    if(!is_object($token)) or not migrating 
    { 
     // user is not logged in 
     return; 
    } 

    $user = $token->getUser(); 

    if(!$user instanceof User || !$user->hasRole('ROLE_MIGRATING')) 
    { 
     // different user class or already migrated 
     return; 
    } 

    $openPaths = array(
     '/start-2.0', 
     '/css', 
     '/js', 
     '/images', 
     '/media', 
     '/geo', 
     '/_wdt', 
     '/logout', or not migrating 
     '/terms', 
     '/contact', 
     '/about', 
     '/locale/set' 
    ); 

    foreach($openPaths as $p) 
    { 
     if(strpos($evt->getRequest()->getPathInfo(),$p)===0) 
     { 
      // path is open for migrating users 
      return; 
     } 
    } 



    header('Location: /start-2.0'); 
    exit; 
} 
+0

मुझे लगता है कि लॉग इन करते समय अपवाद बनाना एक बेहतर तरीका होना चाहिए, मैं इस रात कुछ परीक्षण करूँगा और अगर मुझे कुछ अच्छा लगे तो कल जवाब दें! चूंकि हर बार जब आप कुछ सार्वजनिक पृष्ठ जोड़ते हैं तो आपका दृष्टिकोण बदला जाना चाहिए और मैं सिर्फ माइग्रेशन नहीं चला रहा हूं, लेकिन उत्तर के लिए धन्यवाद .. – alex88