Yii所有发布请求仅对第一次会话的CSRF验证失败

时间:2014-11-28 21:29:31

标签: php session yii csrf

我正在使用此帖子使用会话来获取/设置csrf令牌而不更改代码

http://www.yiiframework.com/wiki/274/how-to-validate-csrf-token-with-session/

如果用户第一次登陆页面然后执行POST请求,则所有用户都会失败。 (所有POST请求都发送CSRF令牌)。但是如果用户刷新页面,则重新加载后的所有POST请求都将通过!

经过大量调试后,我发现第一页加载时收到的CSRF令牌将不再与会话中保存的值匹配。当用户重新加载页面时,csrf标记将更改为CSRF会话的值,并且所有POST请求都会成功。

我将会话自动启动设置为true。我也尝试过在会话中使用cookie,但同样的问题也会发生。我也试过用户状态。

自从我第一次开始这个为期一年的项目以来,我可能遇到过这个问题,但直到现在才注意到它,只有当它第一次加载页面时才会发生。

我的所有控制器都扩展了一个扩展Controller的ParentController。它只有一个构造函数和init。 我试图找出它被调用两次,但到目前为止没有。

 public function __construct($id,$module=null)
 {

       parent::__construct($id,$module);    

        // do stuff
 }
 public function init()
{       
        // do stuff
 }
下面的

是页面加载后的POST请求的示例

$.ajax({
   type: "POST",
   data: {name:xName,id:xID,YII_CSRF_TOKEN:CSRFTokenValue},
   url: "/page/logPageView/",
   success: function(data){
   }
});

关于我应该在哪里看的任何想法?这种奇怪行为的任何可能原因?

1 个答案:

答案 0 :(得分:0)

我发现问题与缓存有关。我最近添加了cloudflare缓存,这导致用户第一次从缓存的内容中获取旧的CSRF令牌。这就是为什么我无法在我的localhost或测试服务器上重新生成它的原因,因为它们没有被缓存。

我通过添加ajax调用来解决这个问题,以便在页面加载时获取新的令牌,然后将此令牌用于将来的帖子。并确保" getFreshToken"呼叫没有缓存。