编辑:
在问了这个问题之后,我得到了一系列新的见解,这些见解告诉我问题是什么,而且它肯定与所描述的服务器迁移没有任何关系。
这两个答案说明了如何在CakePHP 2和3中“修复”这个问题,但请记住,这可能会带来安全风险。CSRF组件是一个重要的安全特性,不应该轻易禁用。
原始问题:
我将我的CakePHP 3项目从笔记本电脑上的XAMPP迁移到了服务器上的XAMPP。自从我激活安全组件后,Cake就向我抛出了一个错误。下面是直接来自错误日志的错误:
2016-05-21 20:32:01 Error: [Cake\Controller\Exception\AuthSecurityException] '_Token' was not found in request data.
Request URL: /Users/addUser
Referer URL: http://localhost/users/add_user
Stack Trace:
# 0 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Controller\Component\SecurityComponent.php(324): Cake\Controller\Component\SecurityComponent->_validToken(Object(App\Controller\UsersController))
# 1 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Controller\Component\SecurityComponent.php(130): Cake\Controller\Component\SecurityComponent->_validatePost(Object(App\Controller\UsersController))
# 2 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Event\EventManager.php(386): Cake\Controller\Component\SecurityComponent->startup(Object(Cake\Event\Event))
# 3 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Event\EventManager.php(356): Cake\Event\EventManager->_callListener(Array, Object(Cake\Event\Event))
# 4 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Event\EventDispatcherTrait.php(78): Cake\Event\EventManager->dispatch(Object(Cake\Event\Event))
# 5 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Controller\Controller.php(495): Cake\Controller\Controller->dispatchEvent('Controller.star...')
# 6 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(109): Cake\Controller\Controller->startupProcess()
# 7 C:\xampp\htdocs\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(87): Cake\Routing\Dispatcher->_invoke(Object(App\Controller\UsersController))
# 8 C:\xampp\htdocs\webroot\index.php(37): Cake\Routing\Dispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
# 9 {main}
我在StackOverflow上找到了CakePHP security component blackholing login (data[_Token][key] field not generated),但没有其他相关信息来说明问题的原因。在Appcontroller中:
public function initialize()
{
parent::initialize();
$this->loadComponent('Security');
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
5条答案
按热度按时间eagi6jfj1#
这个错误与
_TOKEN
有关。当我们创建一个CakePHP表单,然后基于输入字段,CakePHP会生成名为_TOKEN
的隐藏字段。例如:
现在,在检查HTML时,您应该会看到表单中的_TOKEN值:
如果您没有任何可见字段,则_Token将为空。如果您需要具有不可见字段,则只需在表单或字段上添加一个隐藏类。
无论如何,回到主要问题。这个错误是由于
_TOKEN
字段的缺失引起的。在上面的例子中,我会在进行 AJAX 调用之前序列化我的表单。请注意,在 AJAX 中,我使用的是来自Cakephp表单的URL,而不是在ajax中硬编码。这样,它将使用Cakephp URL助手。
1dkrff032#
编辑@无敌评论后
禁用csrf和安全组件时要小心,它们提供了针对csrf和表单篡改、强制ssl、http方法等https://book.cakephp.org/3.0/en/controllers/components/security.html的保护。
此答案仅显示如何禁用它们,以防您确定该请求不需要它们。
原始答案
在 AJAX 请求的情况下,您可以禁用该特定操作的安全组件(相当于在cake 2.x中将该操作设置为解锁)
将此代码放入控制器的
beforeFilter
中**正在禁用csrf组件 *book.cakephp.org/3.0/en/controllers/components/csrf.html#disabling-the-csrf-component-for-specific-actions
禁用安全组件http:book.cakephp.org/3.0/en/controllers/components/security.html#disabling-security-component-for-specific-actions
bqucvtff3#
UPDATE:另外,确保你没有忘记
echo $this->Form->end();
,因为它添加了所有必要的令牌。原始答案如下。UPDATE:您在提交表单created separately via
new \Cake\View\ViewBuilder()
时也可能会遇到此问题正确的答案确实是花一些时间更新代码,使其符合安全组件的指导原则。禁用组件或解锁特定操作是一种变通办法,而不是解决方案。
关于
_Token
的几个不那么明显的事情。<form>
,用于构建重复的、几乎相同的 AJAX 请求(一个字段在javascript循环中不断更新并重新提交;不要问为什么)。*
_Token
链接到表单操作URL。您不能让占位符表单指向例如javascript:;
,并让使用其令牌签名的实际请求转到其他终结点*
_Token
是可重用的。可以发出多个使用同一个令牌签名的请求(即,一次又一次地提交同一个表单),而不是像我想象的那样是一次性令牌因此,我所做的是将我的可变信息放入
type="text"
输入和display:none
它,而不是使用type="hidden"
输入,这将属于表单篡改保护。然后,我对表单进行serialize()
'd,并将其放入jQuery.ajax()
数据属性。当然,一个人可以采取简单的
unlockedActions
路线,但你可能会很高兴,如果你不这样做。mw3dktmi4#
@Invincible的答案是好的,但是以这种方式应用csrf似乎是一场应用和维护的噩梦,因为我们的应用程序中已经有大约20个 AJAX 。
所以我使用Cakephp 3 - element来帮助抽象一些代码。如果你也想抽象csrf令牌,我将我的代码粘贴在这里供其他人参考。
下面是代码:
元素: AJAX _元素.ctp
要在页面上添加 AJAX ,请执行以下操作:
一些页面.ctp
注意:在上面,
year
是一个自定义参数,需要与token
参数沿着传递给 AJAX ,如果不这样做,cakephp将输出安全错误。gudnpqoy5#
我也遭受了同样的事情,但它被解决了