使用通过Yii2中的链接提交AJAX时的CSRF问题

时间:2015-08-21 18:24:32

标签: php ajax yii yii2

我正在使用Yii2并且一直在使用通过AJAX执行POST的链接来检索一些数据并且它一直正常工作;但是我注意到如果我从页面中删除一个表单它不再有效,并且由于某种原因不会在标题中发送CSRF令牌。

我还在两个情况下的页面上有几个隐藏表单。

以下是两种情况:

工作情况:

页面上的所有CSRF都是相同 - 名为meta的{​​{1}}标记,页面上的主要表单以及所有隐藏的表单,它们都使用SAME CSRF令牌,这与请求在标头中发送的令牌相同。

...现在我更改了方案,因此我可以生成非工作版本。

不工作情况:

在这种情况下,页面上没有主要表格。名为csrf-token的{​​{1}}标记与上一个请求具有不同的CSRF令牌,但由于某种原因,所有隐藏表单都具有来自 previous <的令牌/ em>请求/页面加载。

当我点击链接时,通过AJAX 没有的POSTF令牌在标题中发送。

如果重要:

表单加载了meta,而隐藏表单加载了csrf-token

知道这里发生了什么吗?为什么不起作用?为什么隐藏的表单具有先前请求中的CSRF令牌?

1 个答案:

答案 0 :(得分:1)

工作:好的,所以我对这个问题的理解是当你使用ActiveFrom时它会创建一个新的CSRF令牌并存储在一个cookie中,比如xxxxxx,所以主表单和相应的HTML表单在该页面从此cookie读取csrf值。

不工作现在,您进入新页面所以Yii引擎在服务器端创建了一个csrf(这就是为什么你看到带有新csrf令牌的元标记),除非你打电话在ActiveForm中,cookie无法在客户端更新。因此,所有其他HTML表单都尝试从cookie值读取以获取csrf值,该值最终为旧值。

因此,除非你可能调用一个动态创建令牌的函数,否则我看不到值正在改变。所以价值保持不变。

我的想法是尝试

'_csrf="<?php echo Yii::$app->request->csrfToken ?>" '

在HTML页面中,您没有Main表单来从请求中返回值。

我没有尝试,但应该工作。

或者对于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},
});