我正在使用此帖子使用会话来获取/设置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){
}
});
关于我应该在哪里看的任何想法?这种奇怪行为的任何可能原因?
答案 0 :(得分:0)
我发现问题与缓存有关。我最近添加了cloudflare缓存,这导致用户第一次从缓存的内容中获取旧的CSRF令牌。这就是为什么我无法在我的localhost或测试服务器上重新生成它的原因,因为它们没有被缓存。
我通过添加ajax调用来解决这个问题,以便在页面加载时获取新的令牌,然后将此令牌用于将来的帖子。并确保" getFreshToken"呼叫没有缓存。