首页 文章

如何在功能测试中使用令牌模拟身份验证时正确设置用户名

提问于
浏览
1

我需要编写一个功能测试来测试每个角色是否具有对页面的正确访问权限 .

为了做到这一点,我是simulating authentication with a token,但我稍微编辑了logIn方法,只是用自定义 $username$role$firewall 调用它:

protected function logIn($username, $role, $firewall)
{
    $session = $this->client->getContainer()->get('session');

    $token = new UsernamePasswordToken($username, null, $firewall, $role);
    $session->set('_security_' . $firewall, serialize($token));
    $session->save();

    $cookie = new Cookie($session->getName(), $session->getId());
    $this->client->getCookieJar()->set($cookie);
}

所以我可以调用它来指定哪些角色应该有假用户:

$this->logIn('my_username@example.com', ['ROLE_USER'], "my_firewall");

然后我可以测试是否允许用户访问某些路由:

// check if the access is correctly denied to the ROLE_USER
$this->client->request('GET', '/route-not-allowed-to-user');
        $this->assertEquals(403, $this->client->getResponse()->getStatusCode());

// check if the access is correctly allowed to the ROLE_USER
$this->client->request('GET', '/route-allowed-to-user');
        $this->assertNotEquals(403, $this->client->getResponse()->getStatusCode());

这些断言起作用,唯一的问题是在 route-allowed-to-user 的视图中我使用twig输出用户名:

{{ app.user.username }}

但它失败了 . 我得到状态代码 500 而不是 200 ,并出现以下错误:

无法访问空变量的属性(“用户名”)...

因为没有设置 app.user .

在使用令牌模拟身份验证时,如何正确设置用户?

2 回答

  • 0

    我认为这是因为您没有通过身份验证过程而只是创建了用户令牌,该用户令牌没有触发存储用户的用户名,角色等的Symfony事件 .

    我最近通过登录表单填写数据并发送它来做类似的事情 . 就像我正在进行真正的登录尝试一样,效果很好 .

    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    abstract class AuthenticatedTestCase extends KernelTestCase
    {
        static protected $client;
    
        static public function setUpBeforeClass()
        {
            parent::setUpBeforeClass();
            self::$client = static::$kernel->getContainer()->get('test.client');
        }
    
        static public function login($login, $password)
        {    
            $crawler = self::$client->request('GET', '/test_admin/login');
            $form = $crawler->filter('input[type="submit"]')->form([
                '_username' => $login,
                '_password' => $password,
            ]);
    
            self::$client->submit($form);
    
            // Redirect after successful login
            self::assertEquals(302, self::$client->getResponse()->getStatusCode());
    
            self::$client->followRedirect();
    
            if (200 === self::$client->getResponse()->getStatusCode()) {
                // Redirected URL is OK
                // ...
            }
        }
    }
    
  • 0

    我通过编辑 logIn 方法解决了如下问题:

    protected function logIn($username, $password, $firewall)
    {
        $session = $this->client->getContainer()->get('session');
        $authenticationManager = $this->client->getContainer()->get('security.authentication.manager');
    
        $token = $authenticationManager->authenticate(
            new UsernamePasswordToken(
                $username,
                $password,
                $firewall
            )
        );
    
        $session->set('_security_' . $firewall, serialize($token));
        $session->save();
    
        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);
    }
    

    并使用doctrine data fixtures来设置用户和角色 .

相关问题