为了防止恶意用户通过模拟点击事件绕过验证码验证,我们需要采用一些更复杂的方法。以下是一些常见的防御措施:
-
隐藏验证码字段:
通过使用CSS隐藏一个额外的表单字段(honeypot),并在提交时检查该字段。如果该字段被填充,说明是机器人提交的表单。 -
使用时间戳:
在表单生成时记录时间戳,并在提交时验证提交时间。如果提交时间太短,可能是机器人提交的。 -
服务器端验证:
始终在服务器端进行验证,不信任客户端发送的任何数据。 -
验证码复杂性:
提高验证码的复杂性,如图片验证码、文字验证码或简单的数学问题。
下面是改进后的示例,综合了上述方法来防止模拟点击事件:
前端部分
- 创建HTML页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Captcha Verification</title> <style> .checkbox-container { display: flex; align-items: center; margin: 20px; } .checkbox-container input { margin-right: 10px; } .hidden-field { display: none; } </style> </head> <body> <form id="captcha-form" action="/verify-captcha" method="POST"> <div class="checkbox-container"> <input type="checkbox" id="human-check" name="human-check" required> <label for="human-check">I am not a robot</label> </div> <input type="hidden" name="timestamp" id="timestamp"> <input type="text" class="hidden-field" name="honeypot" value=""> <button type="submit">Submit</button> </form> <script> // Set timestamp when the form is loaded document.getElementById('timestamp').value = Date.now(); document.getElementById('captcha-form').addEventListener('submit', function(event) { const checkbox = document.getElementById('human-check'); if (!checkbox.checked) { event.preventDefault(); alert('Please confirm you are not a robot.'); } }); </script> </body> </html>
后端部分
- 后端验证
const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.post('/verify-captcha', (req, res) => { const currentTimestamp = Date.now(); const submittedTimestamp = parseInt(req.body.timestamp, 10); const timeDiff = currentTimestamp - submittedTimestamp; // Honeypot check if (req.body.honeypot) { return res.send('Captcha verification failed! Honeypot field should be empty.'); } // Time check if (timeDiff < 2000) { // less than 2 seconds return res.send('Captcha verification failed! Form submitted too quickly.'); } // Checkbox check if (req.body['human-check']) { res.send('Captcha verification successful!'); } else { res.send('Captcha verification failed!'); } }); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); });
说明
-
隐藏字段:
- 添加一个隐藏的文本字段(honeypot)。正常用户不会填写这个字段,但机器人可能会填写所有字段。
-
时间戳:
- 在页面加载时生成时间戳,并在表单提交时一起提交。后端验证提交时间是否合理。
-
服务器端验证:
- 在服务器端进行所有验证,包括honeypot字段检查、时间检查和复选框检查。
通过这些方法,可以有效防止模拟点击事件和其他常见的自动化攻击。