如何在 Cakephp 3 中的 ajax 调用中定义 CSRF 令牌。另外,对于某些 ajax 请求,如何关闭 CSRF

How to define CSRF token in ajax call in Cakephp 3. Also How CSRF can be off for some ajax requests

在启用 Csrf 组件时的 Cakephp3 中。我如何在 ajax 通话中使用它。 ajax csrf token 的这个beforeSend 参数设置在header 中。 csrfToken 的值是多少?因为它给出了错误

csrfToken is not defined

beforeSend: function(xhr){
    xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},

另外,如何为某些 ajax 调用禁用 Csrf 组件。

CSRF 组件将当前令牌作为 _csrfToken 写入请求参数,您可以通过请求对象的 param() 方法(或 CakePHP 3.4 的 getParam() )获取它:

beforeSend: function(xhr){
    xhr.setRequestHeader(
        'X-CSRF-Token',
        <?= json_encode($this->request->param('_csrfToken')); ?>
    );
},

要使令牌对您的所有脚本可用,例如,您可以将其作为布局模板中的变量全局可用:

<script>
var csrfToken = <?= json_encode($this->request->param('_csrfToken')) ?>;
// ...
<script>

然后您可以在所有 AJAX 请求中轻松使用它:

setRequestHeader('X-CSRF-Token', csrfToken);

CSRF 组件可以通过从控制器事件管理器中删除来禁用。您必须确定在什么条件下需要执行此操作,例如对于特定操作,如下所示:

public function beforeFilter(\Cake\Event\Event $event)
{
    parent::beforeFilter($event);

    if ($this->request->param('action') === 'actionXyz') {
        $this->eventManager()->off($this->Csrf);
    }
}

如果您使用的是 CSRF 中间件,则令牌仍可用作名为 _csrfToken 的请求参数,但禁用中间件的方式不同,请参见 [=18= 示例]

另见

每个表单都有一个隐藏的 _csrfToken 字段,当您启用 Csrf 组件时,该字段会自动添加。现在你可以通过 jquery 像 $('[name="_csrfToken"]').val().

轻松获取该字段的令牌

ajax 调用将如下所示:

$.ajax({
   url: 'someUrl',
   headers : {
      'X-CSRF-Token': $('[name="_csrfToken"]').val()
   },
   type: 'post',
   ...
});

CakePHP 3

Please do not unlock fields/disable CSRF security component for any particular action. This is important for the form security.

for those who are getting "The request has been black-holed." ,"form tampered error", "you are not authorized to access that location." or "unexpected field in POST data". It is mainly due to the CSRF component working as expected.

禁用或修改它不是解决方案。请遵循正确的方法,而不是禁用。 在上述情况下,请尝试序列化表单,这应该会产生魔力。

var el = $("#xyzForm");

var ajaxTPCalls = el.serializeArray();
  $.ajax({
                            type: el.attr('method'),
                            async: true,
                            url:  el.attr('action'),
                            data: ajaxTPCalls,
                            dataType: "json",
                            cache: false,
                            success: function (data) {

                                toastr.success(data.message, data.title);
                            },
                            error: function (jqXHR) {
                                if (jqXHR.status == 403) {
                                    $("body").html(jqXHR.responseText);
                                }
                            }
                        });

这样您不会禁用 CSRF 或解锁任何字段。