0

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

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

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

我将FOSUserBundle v2.0.2Symfony 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
4

2 回答 2

0

我不希望用户能够选择他们的组,而是由系统内部管理。对于注册,使用 FOS 的工作并不多。我所需要的只是用一组新的学说键约束覆盖用户实体。我在扩展 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 并添加一组具有组约束的新方法:

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 进行了覆盖,以适应登录和密码重置功能的新更改。

于 2018-02-15T16:13:58.987 回答
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;
    }
}
于 2017-12-18T14:37:18.863 回答