
验证码生成与验证实现
生成随机验证码字符串
function generateCaptcha(length = 6) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let captcha = '';
for (let i = 0; i < length; i++) {
captcha += chars.charAt(Math.floor(Math.random() * chars.length));
}
return captcha;
}
绘制图形验证码
function drawCaptcha(canvasId, captchaText) {
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 背景色
ctx.fillStyle = '#f5f5f5';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制干扰线
for (let i = 0; i < 5; i++) {
ctx.strokeStyle = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
ctx.beginPath();
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.stroke();
}
// 绘制验证码文本
for (let i = 0; i < captchaText.length; i++) {
ctx.fillStyle = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
ctx.font = `${20 + Math.random() * 10}px Arial`;
ctx.fillText(
captchaText[i],
10 + i * 25,
30 + Math.random() * 10
);
}
}
验证用户输入
function validateCaptcha(inputId, storedCaptcha) {
const userInput = document.getElementById(inputId).value;
return userInput === storedCaptcha;
}
完整示例实现
<!DOCTYPE html>
<html>
<head>
<title>验证码示例</title>
<style>
#captchaCanvas {
border: 1px solid #ddd;
margin: 10px 0;
}
button {
cursor: pointer;
}
</style>
</head>
<body>
<div>
<canvas id="captchaCanvas" width="200" height="50"></canvas>
<button onclick="refreshCaptcha()">刷新验证码</button>
</div>
<div>
<input type="text" id="captchaInput" placeholder="请输入验证码">
<button onclick="checkCaptcha()">验证</button>
</div>
<p id="result"></p>
<script>
let currentCaptcha = '';
function initCaptcha() {
currentCaptcha = generateCaptcha();
drawCaptcha('captchaCanvas', currentCaptcha);
}
function refreshCaptcha() {
currentCaptcha = generateCaptcha();
drawCaptcha('captchaCanvas', currentCaptcha);
document.getElementById('result').textContent = '';
}
function checkCaptcha() {
const isValid = validateCaptcha('captchaInput', currentCaptcha);
document.getElementById('result').textContent = isValid
? '验证通过'
: '验证码错误';
}
// 初始化
window.onload = initCaptcha;
</script>
</body>
</html>
安全增强建议
- 服务端应存储验证码并与用户提交的进行比对
- 设置验证码过期时间(通常1-5分钟)
- 限制验证码尝试次数防止暴力破解
- 考虑添加滑动验证等更复杂的验证方式
服务端验证示例(Node.js)
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true
}));
// 生成验证码接口
app.get('/captcha', (req, res) => {
const captcha = generateCaptcha();
req.session.captcha = captcha;
req.session.captchaExpire = Date.now() + 300000; // 5分钟后过期
// 这里应该返回图形验证码,简化示例只返回文本
res.json({ captcha });
});
// 验证接口
app.post('/validate', express.json(), (req, res) => {
const { captcha } = req.body;
if (!req.session.captcha || Date.now() > req.session.captchaExpire) {
return res.json({ valid: false, message: '验证码已过期' });
}
const isValid = captcha === req.session.captcha;
if (isValid) {
req.session.captcha = null; // 验证成功后清除
}
res.json({ valid: isValid });
});
app.listen(3000, () => console.log('Server running on port 3000'));