从 6.3 更新到 6.4 后,Symfony CSRF 令牌在测试中无效

问题描述 投票:0回答:1

我在 symfony 6.3.x 上的应用程序和测试都没有问题。 刚刚将 symfony 6.3 升级到 6.4 后,我的应用程序仍然可以工作(正常),但我的测试被破坏了??.

CSRF 令牌无效。

在测试中,我获取表单,提取令牌并将其与数据一起发送。 我不明白为什么我的测试从 6.3 到 6.4 的变更日志被破坏了。

就像在表单和提交之间重置令牌一样。

测试示例:

  /**
 *
 * @test
 */
public function foo(): void
{

    $client = static::createClient();

    $usersRepository = static::getContainer()->get(UsersRepository::class);
    $userAdmin = $usersRepository->findOneBy(['username'=>'Admin']);
    $client->loginUser($userAdmin);

    $formName ='Means';
    $this->controllerName='Means';

    $client->xmlHttpRequest('POST', '/datagridFormAdd/Means');
    $this->assertResponseIsSuccessful('Add Form: Status code 2xx ');
    //*****************************
    $responseData = json_decode($client->getResponse()->getContent(),true);
    $pos = strpos($responseData['form'], 'name="'.$this->camelCaseToSnakeCase($formName).'"');
    $this->assertNotFalse($pos, 'Formulaire Add non trouvé pour '.$formName);

    //token Csrf
    $pos1 = strpos($responseData['form'], '[_token]" value="');
    $rest = substr($responseData['form'], $pos1+17);
    $tokenCsrf= substr($rest, 0,-11);
    var_dump($tokenCsrf);
    $dataArray['_token'] = $tokenCsrf;

    // Request a specific page
    $client->xmlHttpRequest('POST', '/datagridAddUpdate/'.$this->controllerName,$dataArray,[]);
    $this->assertResponseIsSuccessful('Status code 2xx pour datagridAdd : '.$this->controllerName);
    // Validate a successful response and some content
    $this->assertResponseIsSuccessful();

}

表单中的令牌与请求转储中的令牌不同。 表单标记:

"_token" => "11f391.ZfAYEklbDgUUoSZE3pVHNCfKgYs6WXSguehy-p_xB_g.NMNeIzkRY3JVwxYWteZ1DUj7yO1LLEX22oE3s_GoMq49qVBNLT9ibkTL"

请求转储:

 #storage: Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage 
//...
  "_csrf/MeansToken_item" => "Q3F1pJmwAb0Rks29o1Ifqu1VciEInY5VXYH_ddlkPjk"

我尝试禁用 kernel.reset 但它不起作用。 (https://symfony.com/doc/current/testing.html#multiple-requests-in-one-test

    class Kernel extends BaseKernel implements CompilerPassInterface
{
    use MicroKernelTrait;

    public function process(ContainerBuilder $container): void
    {
        //Pour les tests, sinon le token CRSF est effacé entre les request du client
        if ('test' === $this->environment) {
            // prevents the security token to be cleared
            $container->getDefinition('security.token_storage')->clearTag('kernel.reset');

            // prevents Doctrine entities to be detached
            $container->getDefinition('doctrine')->clearTag('kernel.reset');

        }
    }

}

我的问题:

  1. 我不明白为什么我的测试在从 6.3 到 6.4 的变更日志方面被破坏了
  2. 如何纠正?
symfony testing phpunit csrf csrf-token
1个回答
0
投票

你找到解决办法了吗?

我不明白类似的事情。我创建令牌并将其传递给模板。

每次刷新都会重新生成token:

$expectedToken = $csrfTokenManager->getToken('_mysecret_csrf_token')->getValue(); //bba0920c884cf93c0bdaa8fbf.-EEwG_RGb1YwNQuxeaYCDDboDth3CbvTsdZT1wHTA3Y.1StTarsqCBJbTXjfNfNkRm68aIk0MIzq25ACg3mGbh6pMXh4nyE9AURnSg

然后在模板中我手动将此令牌更新为“123”并提交

if($request->isMethod(Request::METHOD_POST)) {
            $submittedToken = $request->getPayload()->get('token'); // NOTICE 123 123bba0920c884cf93c0bdaa8fbf.-EEwG_RGb1YwNQuxeaYCDDboDth3CbvTsdZT1wHTA3Y.1StTarsqCBJbTXjfNfNkRm68aIk0MIzq25ACg3mGbh6pMXh4nyE9AURnSg
            if ($this->isCsrfTokenValid('_mysecret_csrf_token', $submittedToken)) {
                
                echo 'ok';
            } else {
                echo 'Invalid CSRF token.';
            }

它会打印正常,但是我在提交的令牌中添加了“123”,但是当我将提交的令牌更改为完全不同的东西(例如“Hi Peter”)时,它将打印无效的CSRF令牌我认为那些生成和提交的令牌必须完全匹配而不是部分匹配

© www.soinside.com 2019 - 2024. All rights reserved.