我正在使用 Yii2
并且一直在使用通过 AJAX 执行 POST 的链接来检索一些数据并且它一直工作正常;但是我注意到,如果我从页面中删除一个表单,它就不再有效,并且出于某种原因不会在标题中发送 CSRF token 。
我在页面上还有几个隐藏表单,它们在两种情况下都存在。
下面是两种情况的总结:
工作情况:
页面上的所有 CSRF 都是相同 - 名为 csrf-token
的 meta
标记,页面上的主要表单以及所有隐藏的表单,它们都使用相同的 CSRF token ,这与请求的 header 中发送的 token 相同。
...现在我更改场景以便生成非工作版本。
不工作的情况:
在这种情况下页面上没有主窗体。名为 csrf-token
的 meta
标签具有与上次请求不同的 CSRF token ,但由于某种原因,所有隐藏表单都具有相同的 CSRF来自上一个请求/页面加载的 token 。
当我点击通过 AJAX POST 的链接时,没有 CSRF token 被发送到标题中。
如果重要:
主 表单加载ActiveForm::begin(...)
而隐藏 表单加载Html::beginForm(...)
.
知道这里发生了什么吗?为什么它不起作用?为什么隐藏的表单具有先前请求的 CSRF token ?
最佳答案
工作: 好的,所以我对这个问题的理解是,当您使用 ActiveFrom 时,它会创建一个新的 CSRF token 并存储在一个 cookie 中,例如 xxxxxx,因此主表单和相应的 HTML 表单在该页面从该 cookie 中读取 csrf 值。
不工作: 现在,您进入了一个新页面 所以 Yii 引擎在服务器端创建了一个 csrf(这就是为什么您会看到带有新 csrf 标记的元标记),除非您调用ActiveForm,无法在客户端更新 cookie。因此,所有其他 HTML 表单都尝试从 cookie 值中读取以获取 csrf 值,该值最终成为旧值。
因此,除非您有可能调用一个动态创建 token 的函数,否则我看不到值会发生变化。所以值(value)保持不变。
我的想法是尝试
'_csrf="<?php echo Yii::$app->request->csrfToken ?>" '
在没有主窗体的 HTML 页面中从请求返回值。
我没试过,但应该可以。
或者对于 Ajax
<head>
.......
<?= Html::csrfMetaTags() ?>
</head>
var csrfToken = $('meta[name="csrf-token"]').attr("content");
$.ajax({
url: 'request',
type: 'post',
dataType: 'json',
data: {param1: param1, _csrf : csrfToken},
});
关于php - 通过 Yii2 中的链接使用 AJAX 提交时的 CSRF 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32147040/