Symfony 3 通过手机阵列登录

Posted

技术标签:

【中文标题】Symfony 3 通过手机阵列登录【英文标题】:Symfony 3 login by array of phones 【发布时间】:2017-02-14 20:14:05 【问题描述】:

美好的一天!我想登录我的用户,这是一项微不足道的任务。但问题是通过值数组检查用户!

例如,我有实体用户和电话。用户有很多电话。所以我需要通过它拥有的所有手机登录用户。如何使用安全包的默认工具来做到这一点?

我没有找到任何像我这样的问题,并阅读了有关 Symfony 安全性的所有文档。我唯一想做的就是创建自定义提供程序。但我认为它不能解决我的问题。

亲爱的symfone们,有什么想法吗? :)

【问题讨论】:

如果我理解的话,你会用电话号码代替用户名吗?因此一个用户可以使用多个电话 ID 进行身份验证 你需要编写一个自定义的身份验证证明者(就像在这个文档中的 symfony.com/doc/current/security/… 一样)并使用新的 UsernamePasswordToken (api.symfony.com/3.0/Symfony/Component/Security/Core/…) 对你的用户进行身份验证 【参考方案1】:

你必须在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 并有一个自定义存储库用于实现接口Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface 的示例UserRepository。 您的 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;

    ....
    ....

  

【讨论】:

一切都好,除了一个:需要在 getUsername() 方法中指向什么才能返回?第二个问题:如果我没有列用户名,我该怎么办?例如,只是“名称”? 字段用户名不是强制性的,但方法 getUsername() 是。该方法用于检索用户的登录信息。在您的情况下,您可以实现它以返回用户的电话号码之一。 对不起,但我需要问一下:安全包使用的 getUsername() 在哪里?是否有重要作用,特别是什么作用?您写道,它可以退回一部手机。那么什么手机呢?那参与登录?请告诉我更多细节,或者一些链接,它描述了这一点。非常感谢。 getUsername() 方法是我谈到的 UserInterface 的一部分。您可以通过这些链接了解更多信息 symfony.com/doc/current/security/entity_provider.html 和 api.symfony.com/3.1/Symfony/Component/Security/Core/User/…。希望对您有所帮助。 我忘了说“非常感谢”,因为我决定了我的问题! ;)

以上是关于Symfony 3 通过手机阵列登录的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 自定义身份验证:用户登录但未通过身份验证

symfony 3.3中的单个会话实现

如何通过伪造登录来测试 Symfony 2 中的 ACL

Symfony 3 无法使用 ajax 登录

Symfony2:如何手动登录用户? [复制]

Symfony 2.5.6 打破登录?