Symfony2 FosUserBundle自定义登录查询



我在Symfony2项目中使用FosUserBundle,我有登录工作,我现在想进一步自定义登录,包括检查id以及用户名,电子邮件和密码。我有一个用户实体在Entity文件夹,我有一个UserRepository在Repository文件夹

  • 如何自定义Fos UserBundle登录以在其查询中包含id
  • 我可以做到这一点的不同方法列表是什么
  • 欢迎任何其他改进代码的建议

谢谢

用户实体:

<?php
    namespace ExampleBundleExampleBundleEntity;
    use FOSUserBundleEntityUser as BaseUser;
    use DoctrineORMMapping as ORM;
    use SymfonyComponentValidatorConstraints as Assert;
 /**
  * User
  *
  * @ORMTable(name="Example_user")
  * @ORMEntity(repositoryClass="ExampleBundleExampleBundleRepositoryUserRepository")
  */
class User extends BaseUser {
/**
 * @var integer
 *
 * @ORMColumn(name="id", type="integer")
 * @ORMId
 * @ORMGeneratedValue(strategy="AUTO")
 */
protected $id;
/*
*  some Class properties here 
*
*/
/**
 * Get id
 *
 * @return integer 
 */
public function getId() {
    return $this->id;
}
/*
* some setters and getters here
*/
}

User Repository

<?php
  namespace ExampleBundleExampleBundleRepository;
  use DoctrineORMEntityRepository;
  use SymfonyComponentSecurityCoreUserUserProviderInterface;
  use ExampleBundleExampleBundlesiteConfig;
  class UserRepository extends EntityRepository implements UserProviderInterface{
public $university = siteConfig::university_id;
/**
 * 
 * @param type $username
 */
public function FindUsernameOrEmailInUniversity($username, $universityId) {
    return  $this->createQueryBuilder('user')
            ->where('user.university_id = :universityId')
            ->andWhere('user.username = :username OR user.email = :email')
            ->setParameter('universityId', $universityId)
            ->setParameter('username', $username)
            ->setParameter('email', $username)
            ->getQuery()
            ->getOneOrNullResult();
}
/**
 * 
 * @param type $username
 */
public function loadUserByUsername($username) {
    $user = $this->FindUsernameOrEmailInUniversity($username, $this->university); //check order of parameters use type hinting
    if(!$user){
        throw new SymfonyComponentSecurityCoreExceptionUsernameNotFoundException('User Name '.$username.' Not Found');
    }
    return $user;
}
/**
 * 
 * @param SymfonyComponentSecurityCoreUserUserInterface $user
 */
public function refreshUser(SymfonyComponentSecurityCoreUserUserInterface $user) {
    return $user;
}
/**
 * 
 * @param type $class
 */
public function supportsClass($class) {
    return ;
}
}

Security.yml

# app/config/security.yml
security:
    encoders:
        FOSUserBundleModelUserInterface: bcrypt
role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
    fos_userbundle:
        entity: { class: ExampleBundleExampleBundleRepositoryUserRepository }
firewalls:
    main:
        pattern: ^/
        form_login:
            provider: fos_userbundle
            csrf_provider: security.csrf.token_manager # Use form.csrf_provider instead for Symfony <2.4
        logout:       true
        anonymous:    true
access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin/, role: ROLE_ADMIN }

这是我得到的错误

The class 'ExampleBundleExampleBundleRepositoryUserRepository' was not found in the chain configured namespaces ExampleBundleExampleBundleEntity, FOSUserBundleEntity

创建一个扩展FOSUserBundleDoctrineUserManager的实体文件夹内的类(我假设有一个名为siteConfig.php的类,具有由db查询更新的静态University_id字段)

<?php
namespace ExampleBundleExampleBundleEntity
use FOSUserBundleDoctrineUserManager as BaseUserManager;
use DoctrineORMEntityManager;
use SymfonyComponentSecurityCoreEncoderEncoderFactoryInterface;
use FOSUserBundleUtilCanonicalizerInterface;
use FOSUserBundleModelUserInterface;
use ExampleBundleExampleBundlesiteConfig;
class UserManager extends BaseUserManager {
public function __construct(EncoderFactoryInterface $encoderFactory, CanonicalizerInterface $usernameCanonicalizer, 
                                    CanonicalizerInterface $emailCanonicalizer, EntityManager $em, $class) {
    parent::__construct($encoderFactory, $usernameCanonicalizer, $emailCanonicalizer, $em, $class);
}
/**
 * this overides the findUserByUsernameOrEmail in FOSUserBundleDoctrineUserManager
 **/
public function findUserByUsernameOrEmail($usernameOrEmail) {
    if (filter_var($usernameOrEmail, FILTER_VALIDATE_EMAIL)) {
        return $this->findUserBy(array('emailCanonical' => $this->canonicalizeEmail($usernameOrEmail), 'university' => siteConfig::$university_id));
    }
    return $this->findUserBy(array('usernameCanonical' => $this->canonicalizeUsername($usernameOrEmail), 'university' => siteConfig::$university_id));
}
}

User manager的依赖注入,在services.yml中

ExampleUserManager:
class: namespace ExampleBundleExampleBundleEntityUserManager
     arguments: [@security.encoder_factory, @fos_user.util.username_canonicalizer, @fos_user.util.email_canonicalizer, @fos_user.entity_manager, namespace ExampleBundleExampleBundleEntityUser]

里面的配置。Yml在fos_user

下添加以下配置
service:
    user_manager: ExampleUserManager

内部安全。在提供程序下添加以下

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

首先是类型错误——在为实体行定义存储库类时,有一个额外的括号:

/**
 * User
 *
 * @ORMTable(name="Example_user")
 * @ORMEntity(repositoryClass="ExampleBundleExampleBundleRepositoryUserRepository")
 */
 class User extends BaseUser {

试试这个,我对你的方法做了一些修正:

/**
 * @param type $username
 */
 public function FindUsernameOrEmailInUniversity($username, University $university) {
      return  $this->createQueryBuilder('user') //It should be alias for your entity name, and it could be anything you write, like 'user' or just 'u'
          ->where('user.university = :university')
          ->andWhere('user.username = :username OR user.email = :email')
          ->setParameter('university', $university)
          ->setParameter('username', $username)
          ->setParameter('email', $username)
          ->getQuery()
          ->getOneOrNullResult();
}

你也有getter, setter和属性的大学,电子邮件和用户名?我假设你想让大学作为用户的关系,所以你想要设置适当的学说关系。

最新更新