为了账号安全,请及时绑定邮箱和手机立即绑定

Symfony 测试 - 带有 Guard 身份验证的空令牌

Symfony 测试 - 带有 Guard 身份验证的空令牌

PHP
元芳怎么了 2022-07-09 10:07:33
我的 Symfony Web 应用程序中有一个 Guard 身份验证。我想执行一些单元测试。我无法在我的测试中模拟身份验证。null调用时令牌保持不变$tokenStorage->getToken()。笔记:登录身份验证在dev和环境下工作prod。我看到很多相关主题都没有成功和文档。Symfony 版本:3.4。重现:您可以从此repo(symfony 项目)重现错误。这个 repo 定义了一个User带有自定义约束验证器的实体ExampleValidator。在这个约束中,我需要拥有当前登录的用户。代码示例:手动创建用户后,login测试中使用的函数:private function logIn($firewallName = 'main'){   // dummy call to bypass the hasPreviousSession check   $crawler = $this->client->request('GET', '/');   $session = $this->client->getContainer()->get('session');   /** @var User $user */   $user = $this->entityManager->getRepository(User::class)       ->findOneBy(['email' => 'user1@example.com']);   // you may need to use a different token class depending on your application.   // for example, when using Guard authentication you must instantiate PostAuthenticationGuardToken   $token = new PostAuthenticationGuardToken($user, $firewallName, [new Role('ROLE_CLIENT')]);        self::$kernel->getContainer()->get('security.token_storage')->setToken($token);   $session->set('_security_'.$firewallName, serialize($token));   $session->save();   $cookie = new Cookie($session->getName(), $session->getId());   $this->client->getCookieJar()->set($cookie);}tokenStorage来自(来自服务功能)的用户调用:class ExampleValidator extends ConstraintValidator{    protected $requestStack;    protected $em;    protected $user_id;    public function __construct(RequestStack $request,                                EntityManager $em,                                TokenStorage $tokenStorage){        $this->requestStack = $request;        $this->em = $em;        /** @var User $user */        // Token is always null        $user = $tokenStorage->getToken()->getUser();        $this->user_id = $user != "anon." ? $user->getId() : null;    }    /**     * @param $value     * @param Constraint $constraint     */    public function validate($value, Constraint $constraint)    {        // validation rules ...    }}
查看完整描述

1 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

我相信您的问题的根源是您正在使用多个容器实例。特别是,您的logIn()函数在客户端的容器上运行,但验证器来自您在setUp(). 因此,您logIn()对客户端容器所做的更改不会影响您实际测试的验证器。


在任何地方使用相同的容器,例如来自客户端的容器,应该可以解决这个问题。对存储库的以下更改使测试通过:


diff --git a/tests/AppBundle/Validator/UserTest.php b/tests/AppBundle/Validator/UserTest.php

index f15c854..603e566 100644

--- a/tests/AppBundle/Validator/UserTest.php

+++ b/tests/AppBundle/Validator/UserTest.php

@@ -44,10 +44,7 @@ class UserTest extends WebTestCase{

         $this->container = $this->client->getContainer();

         $this->entityManager = $this->container->get('doctrine.orm.entity_manager');


-        // Set validator

-        $kernel = $this->createKernel();

-        $kernel->boot();

-        $this->validator = $kernel->getContainer()->get('validator');

+        $this->validator = $this->client->getContainer()->get('validator');


         // Create one user

         $this->createOneUser();

@@ -100,7 +97,7 @@ class UserTest extends WebTestCase{

         // you may need to use a different token class depending on your application.

         // for example, when using Guard authentication you must instantiate PostAuthenticationGuardToken

         $token = new PostAuthenticationGuardToken($user, $firewallName, [new Role('ROLE_CLIENT')]);

-        self::$kernel->getContainer()->get('security.token_storage')->setToken($token);

+        $this->client->getContainer()->get('security.token_storage')->setToken($token);


         $session->set('_security_'.$firewallName, serialize($token));

         $session->save();


查看完整回答
反对 回复 2022-07-09
  • 1 回答
  • 0 关注
  • 175 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号