2015-07-13 35 views
0

我有Symfony 2.3項目。安裝了FOS User Bundle和Sonata User Bundle。 現在,我不僅需要通過用戶名和密碼登錄用戶,還需要輸入卡號和PIN碼。 用戶只能有一張卡,但該卡可以與多個用戶連接。 算法是當用戶輸入他的用戶名,密碼,卡號和PIN碼時,我應該檢查所有的數據,以及是否有用戶使用他登錄的數據庫中的卡。但是如果卡信息有效但輸入的用戶數據無效我應該在數據庫中用新用戶的用戶名和密碼註冊並立即登錄。通過Symfony 2中的其他字段驗證並註冊用戶

我已經創建了具有兩個字段和與用戶實體的關係的卡實體。用戶實體從Sonata User Bundle擴展而來。 這是卡實體代碼:

namespace Acme\BoardBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 
use Doctrine\Common\Collections\ArrayCollection; 
use Acme\UserBundle\Entity\User as User; 

/** 
* @ORM\Entity 
* @ORM\Table(name="yam_card") 
*/ 
class Card 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(type="string", length=255) 
    * @Assert\NotBlank() 
    * @Assert\Length(min = "6") 
    * @Assert\Length(max = "6") 
    */ 
    protected $number; 

    /** 
    * @ORM\Column(type="string", length=255) 
    * @Assert\NotBlank() 
    * @Assert\Length(min = "4") 
    * @Assert\Length(max = "4") 
    */ 
    protected $pin; 

    /** 
    * @ORM\OneToMany(targetEntity="Acme\UserBundle\Entity\User", mappedBy="card", cascade={"remove"}) 
    */ 
    protected $users; 


    public function __toString() 
    { 
     return (string)$this->number; 
    } 

    public function __construct() 
    { 
     $this->users = new ArrayCollection(); 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set number 
    * 
    * @param string $number 
    */ 
    public function setNumber($number) 
    { 
     $this->number = $number; 
    } 

    /** 
    * Get number 
    * 
    * @return string 
    */ 
    public function getNumber() 
    { 
     return $this->number; 
    } 

    /** 
    * Set pin 
    * 
    * @param string $pin 
    */ 
    public function setPin($pin) 
    { 
     $this->pin = $pin; 
    } 

    /** 
    * Get pin 
    * 
    * @return string 
    */ 
    public function getPin() 
    { 
     return $this->pin; 
    } 

    /** 
    * Add users 
    * 
    * @param \Acme\UserBundle\Entity\User $users 
    * @return Card 
    */ 
    public function addUser(\Acme\UserBundle\Entity\User $users) 
    { 
     $this->users[] = $users; 

     return $this; 
    } 

    /** 
    * Remove users 
    * 
    * @param \Acme\UserBundle\Entity\User $users 
    */ 
    public function removeUser(\Acme\UserBundle\Entity\User $users) 
    { 
     $this->users->removeElement($users); 
    } 

    /** 
    * Get users 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getUsers() 
    { 
     return $this->users; 
    } 
} 

以及與關係用戶實體的代碼和平:

namespace Acme\UserBundle\Entity; 

use Sonata\UserBundle\Entity\BaseUser as BaseUser; 
use Doctrine\ORM\Mapping as ORM; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 
use \Acme\BoardBundle\Entity\Card; 

/** 
* @ORM\Entity 
* @ORM\HasLifecycleCallbacks 
* @ORM\Table(name="fos_user") 
*/ 
class User extends BaseUser 
{ 
    ... 

    protected $card; 

    /** 
    * Set card 
    * 
    * @param \Acme\BoardBundle\Entity\Card $card 
    * @return Card 
    */ 
    public function setCard(\Acme\BoardBundle\Entity\Card $card) 
    { 
     $this->card = $card; 

     return $this; 
    } 

    /** 
    * Get card 
    * 
    * @return \Acme\BoardBundle\Entity\Card 
    */ 
    public function getCard() 
    { 
     return $this->card; 
    } 
} 

User.orm.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping 
        http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> 

    <entity name="Acme\UserBundle\Entity\User" table="fos_user"> 

     ... 

     <many-to-one field="card" target-entity="Acme\BoardBundle\Entity\Card" inversed-by="users"> 
      <join-column name="card" referenced-column-name="id" /> 
     </many-to-one> 
    </entity> 
</doctrine-mapping> 

問題是什麼類(或接口)我應該重新定義添加兩個額外的參數(卡號和PIN)的檢查,我該如何做?

我發現實現UserProviderInterface的UserProvider類。但是該類有loadUserByUsername()方法,該方法通過用戶名加載用戶,並且已經與用戶對象一起工作。 該課程沒有收到我可以從登錄表單中獲取卡號和PIN碼的回覆對象。 另外我發現了一個解決方案,通過從Symfony Security Core擴展UserChecker類來檢查其他用戶狀態參數。有使用checkPreAuth和checkPostAuth方法,但我也可以使用User對象。 所以我想我應該使用一些聽衆或類似的東西來檢查接收的用戶名,密碼,卡號和PIN碼與請求在我的數據庫中註冊的用戶相等。 但我無法找到輸入點。

回答

0

一旦確定通過的Card有效且屬於User,您可以手動登錄使用。確保觸發InteractiveLoginEvent讓所有聽衆知道登錄發生:

// 'main' is the name of the firewall to login to 
    $token = new UsernamePasswordToken($validatedCard->getUser(), null, 'main', $validatedCard->getUser()->getRoles()); 
    $this->get('security.token_storage')->setToken($token); 

    // Notify the dispatcher, so LoginListener is triggered 
    $loginEvent = new InteractiveLoginEvent($request, $token); 
    $this->get('event_dispatcher')->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent); 
+0

感謝您的迴應!我應該在哪裏添加這段代碼? – VladimirZ

+0

這應該是您的卡的入口點,因此可能是一個常規控制器操作,其中可以將卡數據發佈到該路徑。 – Rvanlaak