Codeigniter4开启CSRF后AJAX二次搜索报403错误怎么解决?
问题原因
- CodeIgniter 4开启CSRF防护后默认每次请求都会生成新的CSRF Hash,旧的Hash请求一次后就会失效
- 你的控制器当前直接返回HTML视图片段,AJAX回调拿到的
data是HTML字符串,无法读取token_value属性,所以会出现undefined,也没法更新下次请求要带的CSRF值,第二次请求就会触发403错误
解决方案
按以下步骤修改代码即可实现无刷新多次搜索:
- 修改控制器,返回JSON格式数据
将视图片段和新的CSRF Hash一起返回,方便前端读取:
public function search() { $result = $this->vendors; if ($this->request->getPost('searchByCode')) { $result->like('code', $this->request->getPost('searchByCode')); }; $data = [ 'vendors' => $result->paginate(10, 'vendors'), 'page' => $result->pager, 'token_value' => csrf_hash() ]; // 改为返回JSON,包含视图HTML和新的token return $this->response->setJSON([ 'table_html' => view('vendors/_vendors', $data), 'new_csrf_hash' => $data['token_value'] ]); }
- 修改前端JS代码,全局存储并更新CSRF值
提前全局存储CSRF的键名和当前Hash,每次请求后更新Hash值:
// 全局存储CSRF参数,页面初始化时赋值 const CSRF_TOKEN_NAME = "<?= csrf_token() ?>"; let currentCsrfHash = "<?= csrf_hash() ?>"; $("#btnSearch").click(function(){ $.post("vendor/search", { "searchByCode": $("input[name='searchByCode']").val(), [CSRF_TOKEN_NAME]: currentCsrfHash }, function(res, status){ // 更新为新的CSRF Hash,供下次请求使用 currentCsrfHash = res.new_csrf_hash; // 渲染表格数据 $("#table_vendors").html(res.table_html); }, 'json'); });
可选临时方案(不推荐生产环境使用)
如果不需要每次请求刷新CSRF,可修改app/Config/Security.php中的配置:
public bool $csrfRegenerate = false;
关闭每次请求重新生成CSRF的配置后,首次加载的Hash可以一直使用,不需要每次请求更新,但安全性会降低。
内容的提问来源于stack exchange,提问作者Othsout
相关产品推荐
相关产品推荐

