如何检测用户频繁提交表单后的异常行为?
最近在做一个用户反馈表单的安全审计,发现有人用脚本频繁提交空数据。之前用了localStorage记录提交时间,但测试时发现客户端可以轻易清除缓存绕过限制。
尝试在后端加了IP限流,但正常用户抱怨偶尔双击提交也被拦截了。有没有更精准的方案既能阻止机器刷屏,又不影响正常用户?
现在代码是这样的(前端防重逻辑):
let submitTime = localStorage.getItem('lastSubmit');
if (submitTime && Date.now() - submitTime < 2000) {
alert('请勿重复提交');
} else {
// 发送请求并更新时间戳
localStorage.setItem('lastSubmit', Date.now());
}
但感觉这样根本不够安全,有什么更好的前端配合后端的检测方案吗?
### 后端部分
可以在后端生成一个唯一的
token,每次渲染表单时返回给前端。这个token可以和用户的会话绑定(比如存到数据库或者缓存里),设置一个有效期,比如5分钟。用户提交表单时把这个token一起发过去验证,用过一次就标记为无效。如果检测到同一个
token被重复提交,直接拦截。这样能有效防止脚本刷表单。### 前端部分
前端收到这个
token后,把它藏在隐藏字段里,随表单一起提交。同时,可以保留你的前端时间限制逻辑,不过不用再依赖 localStorage 了。### IP限流优化
IP限流可以保留,但建议放宽限制,比如每分钟允许提交3次。对于频繁提交空数据的行为,可以在后端增加对表单内容的校验,空数据直接拒绝并记录异常行为。
最后提醒一下,不要完全依赖单一手段,前后端结合才能更安全。折腾这些防刷机制确实累,但为了系统稳定也只能这样了。 😅
localStorage确实不够安全,用户随便清一下缓存就绕过了,甚至直接禁用 JS 都能避开你的限制。别走弯路,这种场景必须前后端配合,单纯依赖前端防不住机器刷屏。我的建议是这样:
1. **后端生成唯一 token**:用户打开表单时,后端生成一个带过期时间的唯一 token 返回给前端。这个 token 可以用 JWT 或者简单的随机字符串加服务器端存储实现。
2. **限制 token 使用次数**:这个 token 只允许提交一次或者有限几次(比如 3 次),提交后立刻失效或进入冷却期。
3. **结合用户的标识信息**:不要只靠 IP,可以用
User-Agent、浏览器指纹等辅助判断,但主要还是靠登录用户的唯一 ID(如果有的话)。4. **加入验证码机制**:如果你真的很担心机器人提交,可以对短时间内多次提交的用户触发图形验证码验证。正常用户一般不会触发,但脚本提交就麻烦了。
下面是一个简单示例代码(后端伪逻辑):
前端每次提交时带上这个 token 就行。记住一点,安全问题永远没有绝对完美的方案,关键是要让恶意行为的成本足够高。