FOSUserBundle:根据电子邮件密码和第三个字段对用户进行身份验证

时间:2017-12-18 14:21:13

标签: symfony fosuserbundle symfony3.x symfony-3.4

如何覆盖 FOSUserBundle ,以便我可以根据以下组合注册/验证用户:

Email ID + Password + GroupID而不只是email + password

因此,电子邮件将不再是唯一的,但email + groupid的组合将使用户具有唯一性(每组)并且可以拥有独立的密码。

我正在使用 FOSUserBundle v2.0.2 Symfony 3.4.x

具有有效登录ID的fos_user表行示例:

ID| EMAIL          | GROUP | PASSWORD
--+----------------+-------+---------
1 | u1@example.com |   10  | xxxxxxxx
2 | u1@example.com |   11  | xxxxxxxx
3 | u2@example.com |   10  | xxxxxxxx
4 | u2@example.com |   13  | xxxxxxxx
5 | u1@example.com |   12  | xxxxxxxx

2 个答案:

答案 0 :(得分:0)

使用Symfony Guard创建基于表单的检查并且登录根本不会太难。

这里需要一些基本课程。 Symfony帮助页面上显示了将其连接到用户安全性,还有其他关于使用它的博客文章。

<?php
namespace App\Security;

use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
// other classes to be used

class UserGroupAuthenticator extends AbstractGuardAuthenticator
{
    // other required methods, see the examples

    // this guard is only supported if there is a 'group' form field
    public function supports(Request $request)
    {
        return $request->get->get('group');
    }

    public function getCredentials(Request $request)
    {
        return array(
            'email' => $request->get->get('email'),
            'group' => $request->get->get('group'),
            'password' => $request->get->get('password'),
        );
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $email = $credentials['email'];
        $group = $credentials['group'];

        // if a User object, checkCredentials() is called
        return $userProvider->loadUserByEmailsAndGroup($email, $group);
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        // check credentials - e.g. make sure the password is valid
        // ....

        // return true to cause authentication success
        return true;
    }
}

答案 1 :(得分:0)

我不希望用户能够选择他们的组,而是由系统内部管理。对于注册,与FOS完成的工作并不多。我所需要的只是使用一组新的学说键约束来覆盖User实体。我在扩展BaseUser的User实体中添加了以下内容:

/**
 * User.
 *
 * @ORM\Table(name="fos_user",
 *     uniqueConstraints={
 *          @UniqueConstraint(name="group_username_unique", columns={"group_id", "username_canonical"}),
 *          @UniqueConstraint(name="group_email_unique", columns={"group_id", "email_canonical"})
 *      }
 * )
 * @UniqueEntity(fields={"group", "usernameCanonical"}, errorPath="username", message="fos_user.username.already_used")
 * @UniqueEntity(fields={"group", "emailCanonical"}, errorPath="email", message="fos_user.email.already_used")
 * @ORM\Entity
 * @ORM\AttributeOverrides({
 *     @ORM\AttributeOverride(name="emailCanonical", column=@ORM\Column(type="string", length=180, nullable=false, unique=false)),
 *     @ORM\AttributeOverride(name="usernameCanonical",column=@ORM\Column(type="string", length=180, nullable=false, unique=false))
 * })
 */
class User extends BaseUser
{
    /* my entity contents here */
}

登录时,这是一个很大的工作。我必须覆盖UserProvider,UserManager,创建CustomUserManager并添加一组具有Group约束的新方法:

public function findUserByUsernameOrEmailAndGroup($usernameOrEmail, $group)
{
    if (preg_match('/^.+\@\S+\.\S+$/', $usernameOrEmail)) {
        return $this->findUserByEmailAndGroup($usernameOrEmail, $group);
    }

    return $this->findUserByUsernameAndGroup($usernameOrEmail, $group);
}

public function findUserByEmailAndGroup($email, $group)
{
    return $this->findUserBy(['group' => $group, 'emailCanonical' => $email]);
}

public function findUserByUsernameAndGroup($username, $group)
{
    return $this->findUserBy(['group' => $group, 'usernameCanonical' => $username]);
}

public function findUserByConfirmationTokenAndGroup($token, $group)
{
    return $this->findUserBy(['confirmationToken' => $token, 'group' => $group]);
}

此外,我在RegistrationController和ResettingController上进行了覆盖,以采用登录和密码重置功能的新更改。