CakePHP 3.7.3:将SecurityComponent与带有SPA的Ajax一起使用



这是启用SecurityComponent的ajax请求的一个经典问题。我主要做SPA。这是主要问题。

我也在使用CSRF组件,它工作得很好:

const response = await axios.post("/items/add.json", data, {
headers: {"X-CSRF-Token": "<?= $this->getRequest()->getParam('_csrfToken') ?>"}
});

不起作用的是发送安全组件的_Token

{message: "'_Token' was not found in request data.", url: "/.../add.json", code: 400,…}

当然,我可以禁用SecurityComponent。

我的请求不需要表单/表单助手,那么问题是,当我不使用传统的基于表单的应用程序时,在这里使用SecurityComponent是否有意义。当然,我希望在某些操作中使用某些post字段/值是有道理的,但我不确定如何将其与SecurityComponent结合使用。

我想我可以用helper创建一个伪表单,并从中提取令牌,但这只生成一次,而且我有一个SPA。

这当然有效:

过滤器前:$this->getEventManager()->off($this->Security);

我只是提供了一个技术答案,而不是对使用SecurityComponent是否有意义发表意见——安全性不是我的强项。

如果你需要从SPA中提交许多AJAX调用,你能通过AJAX请求生成请求表单,然后从中提取令牌吗?这听起来可能有点古怪,但实际上可以做得很巧妙——你提交的每个AJAX请求都可以做你需要它做的事情,然后返回一个新的<form>元素(包含新的令牌)作为其响应的一部分——然后你可以把它藏在不可见的地方,覆盖上一个,并从中检索令牌,用于下一次调用。

当涉及到管理提交时,我发现处理令牌等的最简单方法是将这个答案与序列化相结合(例如jQuery的serialize())。这将整齐地封装所有隐藏的表单值。我的(基于jQuery的)代码如下:

var ele_form = $('#some-form-id');
var ele_csrf = ele_form.find('input[name="_csrfToken"]');
var target_url = ele_form.attr('action'); // form-action is validated, so need to generate this correctly
var csrf_token = ele_csrf.val();
$.ajax({
type: 'POST',
url: target_url,
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
},
data: ele_form.serialize()
});

如果你想更具体地说明你在SPA中发送的请求类型,很乐意详细说明这个例子。

最新更新