You can create your own token, put in session with login content and it's fine. I put comment in code to explain it.
Here is example code:
// Main method that put everything into client's object
public function fillCsrfToken(KernelBrowser $client, string $tokenId): string {
$generated = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
$this->seedSession($client, $this->getCsrfTokenSeed($tokenId, $generated));
return $generated;
}
// Get all seed informations that will be put in session:
// - The CSRF token
// - The login data
private function getCsrfTokenSeed(string $tokenId, string $token): array {
return [SessionTokenStorage::SESSION_NAMESPACE."/{$tokenId}" => $token,
'_security_main' => serialize(new PostAuthenticationToken(new LoginUser("MyUser"), "main", ["ROLE_USER"]))
];
}
// Fill client with all sessions informations
private function seedSession(KernelBrowser $client, array $data): void {
$sessionFactory = $client->getContainer()->get('session.factory');
\assert($sessionFactory instanceof SessionFactoryInterface);
$session = $sessionFactory->createSession();
$session->replace($data);
$session->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
}
Then I use like this:
$client = self::getLoggedClient(); // create session object
$token = $this->fillCsrfToken($client, "tester"); // fill token and get the created one
$client->request('POST', "/test", [ // make the request
"_csrf_token" => $token // with the token
]);