Validation Symfony2:如何考虑当前登录的用户来验证实体?

Validation Symfony2:如何考虑当前登录的用户来验证实体?,validation,symfony,Validation,Symfony,我正在用户实体内使用回调进行自定义验证 因此,我需要获取当前登录用户的用户对象 在控制器中,我可以这样做: $user= $this->get('security.context')->getToken()->getUser(); 但是我应该如何在用户实体内部进行验证呢?如果您想验证具有与外部依赖项相关的任何逻辑的对象(在您的情况下,使用@security.context服务获取当前用户)。。。你应该: 创建自定义验证约束 创建约束要使用的自定义验证程序服务 将@secur

我正在用户实体内使用回调进行自定义验证

因此,我需要获取当前登录用户的用户对象

在控制器中,我可以这样做:

$user= $this->get('security.context')->getToken()->getUser();

但是我应该如何在用户实体内部进行验证呢?

如果您想验证具有与外部依赖项相关的任何逻辑的对象(在您的情况下,使用
@security.context
服务获取当前用户)。。。你应该:

  • 创建自定义验证约束
  • 创建约束要使用的自定义验证程序服务
  • @security.context
    服务注入验证程序
  • 使用此新创建的验证约束验证实体
解决方案在文档章节


说明了为什么必须使用以下红牛验证器

模型/实体

use FamilyGuy\Validator\Constraints\Peter as PeterIsNotAllowedToOrder;

class Order 
{
    /** @PeterIsNotAllowedToOrder/RedBull */
    public $drink;
配置

# app/config/services.yml
services:
    validator.red_bull:
        class: FamilyGuy\Validator\Constraints\Peter\RedBullValidator
        # for symfony < 2.6 use @security.context
        arguments: ["@security.token_storage"]
        tags:
            - name: "validator.constraint_validator"
              alias: "peter_red_bull_constraint_validator"
验证程序:

// For symfony < 2.6 use SecurityContextInterface
// use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

namespace FamilyGuy\Validator\Constraints\Peter;

class RedBullValidator extends ConstraintValidator
{

    /** @var TokenStorageInterface|SecurityContextInterface */
    protected $tokenStorage;

    /** @param TokenStorageInterface|SecurityContextInterface $token_storage */
    public function __construct(TokenStorageInterface $token_storage)
    {
        $this->tokenStorage = $token_storage;
    }

    public function validate($drink, Constraint $constraint)
    {
        $currentUser = $this->tokenStorage->getToken()->getUser()->getName();

        if ($currentUser !== "Peter") {
            return;
        }

        if ( $drink !== "RedBull" ) {
             return
        }

        $this->context->buildViolation($constraint->message)
            ->setParameter('%drink%', $drink)
            ->addViolation()
        ;
    }
//对于symfony<2.6,请使用SecurityContextInterface
//使用Symfony\Component\Security\Core\securitycontenterface;
使用Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
使用Symfony\Component\Validator\Constraint;
使用Symfony\Component\Validator\ConstraintValidator;
命名空间FamilyGuy\Validator\Constraints\Peter;
类RedBullValidator扩展了ConstraintValidator
{
/**@var-TokenStorageInterface | securitycontenterface*/
受保护的存储;
/**@param-TokenStorageInterface | securitycontenterface$token|存储*/
公共函数构造(令牌存储接口$令牌存储)
{
$this->tokenStorage=$token\u storage;
}
公共函数验证($DREEN,Constraint$Constraint)
{
$currentUser=$this->tokenStorage->getToken()->getUser()->getName();
如果($currentUser!==“Peter”){
返回;
}
如果($drink!=“红牛”){
返回
}
$this->context->build违例($constraint->message)
->setParameter(“%drink%”,$drink)
->addViolation()
;
}

您不能也不应该使用
回调
约束对任何外部依赖进行验证

不要试图将任何验证依赖项直接注入域模型或实体中

验证逻辑一般不应出现在实体中


注释已经是实体和symfony验证器之间的某种软耦合。这就是为什么通常建议在条令和验证映射中使用xml配置的原因。

谢谢。但它对我不起作用。SecurityContedeInterface似乎从2.6或其他版本开始就被弃用了。我正在使用symfony 3。更新了ans使用Symfony 2.6+时,
@security.token\u存储提供
getToken()方法,而不是<代码> @ Surviv.Actudio……但你自己也能理解这一点;如果我的答案提供了有价值的洞察力,你可以考虑接受或至少支持它。我是SimfOne的新手,所以我无法自己解决它。无论如何,它现在起作用了!非常感谢!!)我对这个问题的解释非常简洁明了。非常感谢。你对Symfony还有其他有价值的见解吗?你有自己编写的教程吗?我很乐意从你的想法中学习。我喜欢用正确的方式做事,你似乎知道这是怎么回事:)
// For symfony < 2.6 use SecurityContextInterface
// use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

namespace FamilyGuy\Validator\Constraints\Peter;

class RedBullValidator extends ConstraintValidator
{

    /** @var TokenStorageInterface|SecurityContextInterface */
    protected $tokenStorage;

    /** @param TokenStorageInterface|SecurityContextInterface $token_storage */
    public function __construct(TokenStorageInterface $token_storage)
    {
        $this->tokenStorage = $token_storage;
    }

    public function validate($drink, Constraint $constraint)
    {
        $currentUser = $this->tokenStorage->getToken()->getUser()->getName();

        if ($currentUser !== "Peter") {
            return;
        }

        if ( $drink !== "RedBull" ) {
             return
        }

        $this->context->buildViolation($constraint->message)
            ->setParameter('%drink%', $drink)
            ->addViolation()
        ;
    }