我在 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');
}
}
}
我的问题:
你找到解决办法了吗?
我不明白类似的事情。我创建令牌并将其传递给模板。
每次刷新都会重新生成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令牌我认为那些生成和提交的令牌必须完全匹配而不是部分匹配