2016-10-06 9 views
2

Добрый день! Я хочу войти в систему для своих пользователей, и это тривиальная задача. Но проблема заключается в проверке пользователя по массиву значений!Symfony 3 Войти по массиву телефонов

Например, у меня есть пользователь и телефон. У пользователя много телефонов. Поэтому мне нужно войти в систему по всем телефонам, которые у него есть. Как я могу это сделать, используя инструмент безопасности по умолчанию?

Я не нашел ни одного вопроса, как мой, и прочитал всю документацию о безопасности в Symfony. Единственное, что я думал сделать, это создать пользовательский поставщик. Но я не думаю, что это решает мою проблему.

Любые ides, дорогие симфонисты? :)

+0

Если я правильно понимаю, вы будете использовать телефон идентификатор вместо имени пользователя? поэтому один пользователь может пройти аутентификацию со многими идентификаторами телефона. –

+0

U необходимо написать собственный аутентификатор auth (например, в этом документе http://symfony.com/doc/current/security/custom_authentication_provider.html) и аутентифицировать пользователей с помощью нового UsernamePasswordToken (http : //api.symfony.com/3.0/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.html) –

ответ

5

Вы должны установить поставщик безопасности в security.yml

security: 

    # http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers 
... 

    providers: 
     my_db_provider: 
      entity: 
       class: AppBundle:User 
... 

Тогда ваш объект AppBundle:User должен реализует интерфейс Symfony\Component\Security\Core\User\UserInterface и иметь пользовательский репозиторий для примера UserRepository, который реализует интерфейс Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface. Ваш UserRepository класс должен выглядеть следующим образом:

<?php 

use Doctrine\ORM\NonUniqueResultException; 
use Doctrine\ORM\NoResultException; 
use AppBundle\Entity\User; 
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface; 
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; 

class UserRepository extends EntityRepository implements UserLoaderInterface 
{ 

/** 
    * Loads the user for the given username. 
    * 
    * This method must return null if the user is not found. 
    * 
    * @param string $username The username 
    * @return null|Utilisateur 
    * @throws \Exception 
    */ 
    public function loadUserByUsername($username) 
    { 
    //Here you write a custom query to retrive the user base on the fields you require. 
    // Here I have used username, email and phone number 
    $q = $this 
     ->createQueryBuilder('u') 
     ->select('u') 
     ->leftJoin('u.phones', 'p') 
     ->where('u.username = :username or u.email= :email or p.phoneNumber= :phone') 
     ->setParameter('username', $username) 
     ->setParameter('email', $username) 
     ->setParameter('phone ', $username) 
     ->getQuery(); 
    try { 
     $user = $q->getSingleResult(); 
    } catch (NoResultException $e) { 
     throw new UsernameNotFoundException(sprintf('Unable to find an active user AppBundle:User object identified by "%s".', $username), 0, $e); 
    } catch (NonUniqueResultException $ex) { 
     throw new \Exception("The user you provided is not unique"); 
    } 
    return $user; 
    } 
} 

Ваш класс AppByndle:User объект должен выглядеть следующим образом:

<?php 


    use Doctrine\Common\Collections\ArrayCollection; 
    use Doctrine\Common\Collections\Collection; 
    use Doctrine\ORM\Mapping as ORM; 
    use Symfony\Component\Security\Core\User\UserInterface; 

    /** 
    * User 
    * 
    * @ORM\Table(name="user") 
    * @ORM\Entity(repositoryClass="AppBundle\Dao\UserRepository") 
*/ 
class User implements UserInterface 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="username", type="string", length=254, nullable=false, unique=true) 
    */ 
    private $username; 

    .... 
    .... 

    } 
+0

Все хорошо, кроме одного: что нужно указывать в методе getUsername() для возврата? И второй вопрос: что мне делать, если у меня нет имени пользователя столбца? Например, просто «имя»? –

+0

Имя пользователя поля необязательно, но метод getUsername() есть. Этот метод используется для получения логина пользователя. В вашем случае вы можете реализовать его, чтобы вернуть один из номеров телефонов пользователя. –

+0

Извините, но мне нужно спросить: где getUsername() используется комплектом Security? Он имеет важную роль и, в частности, какую роль? Вы написали, что он может вернуть один телефон. Так какой телефон? Это принимало участие в логистике? Скажите мне более подробную информацию или, возможно, ссылку, которая описывает это. Большое спасибо. –