在Form中,为了防止csrf攻击,通常会使用csrf token进行防御,在后台使用$this->security->checkToken()进行检测,但在ajax进行POST提交时,如果不做一些额外的操作,会导致ajax第二次提交时csrf token验证不过。
原因:由于csrf token是每次提交后自动更新的,ajax在第一次提交后,在服务后端csrf token其实已经变了,所以再用原来的key就无法验证通过。
解决方式:需要对页面中的csrf token也进行更新才行。
示例:
后台代码:
public function xxx()
{
$this->view->disable();
if ($this->security->checkToken()) {
echo json_encode(
[
'csrfToken' => [
'key' => $this->security->getTokenKey(),
'token' => $this->security->getToken()
]
]
);
}
}
前端代码:
<button id="haha" key="{{ security.getTokenKey() }}" token="{{ security.getToken() }}" class="btn btn-default">
test
</button>
<script type="application/javascript">
$("#haha").click(function () {
var key = $("#haha").attr('key');
var token = $("#haha").attr('token');
var post_data = {};
post_data[key] = token;
console.log(post_data);
$.ajax({
type: 'POST',
url: '{{ url('xxx/xxx') }}',
data: post_data,
dataType: 'JSON',
success: function (result) {
var res = result['csrfToken'];
$("#haha").attr('key', res.key);
$("#haha").attr('token', res.token);
console.log(res);
}
});
return false;
})
</script>
前端在进行提交后,后台会返回下一次要用的token,前端要更新相应的token数据,以便于下一次正确提交!