表单提交带了CSRF Token后后端还是报无效?
我在登录表单里加了隐藏字段的CSRF Token,用JavaScript从API接口获取的,但每次提交后端还是返回“Token无效”。明明前端能正常拿到Token值,表单也正确显示在hidden input里,这是哪里出问题了?
<form id="loginForm" method="POST" action="/login">
<input name="username" type="text">
<input name="password" type="password">
<input type="hidden" name="csrfToken" value="">
</form>
<script>
fetch('/api/csrf-token')
.then(res => res.json())
.then(data => {
document.querySelector('[name="csrfToken"]').value = data.token;
});
</script>
我检查了网络请求,发现表单提交时POST数据确实带有csrfToken参数,但后端PHP验证时$_POST[‘csrfToken’]总是空的。难道是表单提交方式有问题?或者服务端没正确设置Cookie同源?
$_POST里面,特别是你用的是自定义字段名。你后端需要手动从
php://input里解析 token。我猜你用的是类似$_POST['csrfToken']直接取值的方式,但这种取法在某些情况下会取不到。下面是你需要改的后端代码:前端代码没问题,继续用你现在的逻辑就行。问题就在 PHP 默认处理 POST 数据的方式上,它对安全校验这种高级操作不太友好,得手动捞数据。
另外,检查一下 CSRF Token 的生成逻辑,确保你服务端有存下来(比如存在 session 里),不然验证逻辑也会失败。我之前就是忘了把 token 存 session,前端传对了后端还是报错,吐血。