【发布时间】:2019-10-03 20:44:12
【问题描述】:
测试/TestCase/Controller/FeedbackControllerTest.php:45
public function testAdd()
{
$this->enableCsrfToken();
$this->enableSecurityToken();
$this->session([
'Auth' => [
'User' => [
'id' => 1,
'role' => 'REPR',
]
]
]);
$this->configRequest([
'headers' => ['Accept' => 'application/json']
]);
$_data = [
'crash' => 1,
'details' => 'Lorem ipsum dolor sit amet'
];
$_data = json_encode($_data, JSON_PRETTY_PRINT);
$this->post('/feedback/add', $_data); // <---- 45
$expected = [
'status' => 'success'
];
$expected = json_encode($expected, JSON_PRETTY_PRINT);
$this->assertEquals($expected, (string)$this->_response->getBody());
}
PHPUnit 输出:
1) App\Test\TestCase\Controller\FeedbackControllerTest::testAdd
Cake\Http\Exception\InvalidCsrfTokenException: Missing CSRF token cookie
/vagrant/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php:196
/vagrant/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php:120
/vagrant/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php:106
/vagrant/vendor/cakephp/cakephp/src/Http/Runner.php:65
/vagrant/vendor/cakephp/cakephp/src/Http/Runner.php:51
/vagrant/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php:168
/vagrant/vendor/cakephp/cakephp/src/Http/Runner.php:65
/vagrant/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php:88
/vagrant/vendor/cakephp/cakephp/src/Http/Runner.php:65
/vagrant/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php:96
/vagrant/vendor/cakephp/cakephp/src/Http/Runner.php:65
/vagrant/vendor/cakephp/cakephp/src/Http/Runner.php:51
/vagrant/vendor/cakephp/cakephp/src/Http/Server.php:98
/vagrant/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php:201
/vagrant/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestTrait.php:516
/vagrant/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestTrait.php:413
/vagrant/tests/TestCase/Controller/FeedbackControllerTest.php:45
我已经阅读并尝试了答案中的解决方案:
How to create CSRF token for Cakephp 3 PHPunit testing?
如果我像@ndm 所说的那样添加:
$token = 'my-csrf-token';
$this->cookie('csrfToken', $token);
$data = [
'email' => 'info@example.com',
'password' => 'secret',
'_csrfToken' => $token
];
然后:
Cake\Http\Exception\InvalidCsrfTokenException: CSRF 令牌不匹配。
如何解决?
【问题讨论】:
-
自从引入了
enableCsrfToken()方法以来,不再需要手动设置cookie。尝试从您的测试代码中删除一些位,例如请求配置、安全令牌、会话配置等,看看它是否有任何不同,也许存在某种不兼容。还要确保您没有更改中间件的默认 cookie 名称配置。 -
哦,等等,您正在发布一个 JSON 字符串... IIRC 在这种情况下您仍然需要手动执行此操作,但您必须将令牌作为标头传递 (
X-CSRF-Token)而不是在发布数据中(现在无法测试)。 -
@ndm 如何将有效令牌作为 X-CSRF-Token 传递?
-
您将其作为标题传递,就像您已经在使用
Accept标题一样。 -
我刚刚看过,你肯定需要在传递 JSON 字符串时将其作为标头发送。
标签: cakephp phpunit cakephp-3.7