js验证码的实现
验证码的基本实现原理
验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。
纯前端验证码实现示例
以下是一个简单的数字验证码生成与验证的前端实现:
// 生成随机验证码
function generateCaptcha() {
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let captcha = '';
for (let i = 0; i < 6; i++) {
captcha += chars.charAt(Math.floor(Math.random() * chars.length));
}
document.getElementById('captchaDisplay').textContent = captcha;
return captcha;
}
let currentCaptcha = generateCaptcha();
// 验证用户输入
function validateCaptcha() {
const userInput = document.getElementById('captchaInput').value;
if (userInput === currentCaptcha) {
alert('验证码正确');
return true;
} else {
alert('验证码错误');
generateCaptcha();
return false;
}
}
结合Canvas的图形验证码
更安全的实现方式是通过Canvas生成图形验证码:
function drawCaptcha() {
const canvas = document.getElementById('captchaCanvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 生成随机字符串
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
let captchaText = '';
for (let i = 0; i < 6; i++) {
captchaText += chars.charAt(Math.floor(Math.random() * chars.length));
}
// 绘制背景和干扰元素
ctx.fillStyle = '#f0f0f0';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制文本
for (let i = 0; i < captchaText.length; i++) {
ctx.font = '24px Arial';
ctx.fillStyle = getRandomColor();
ctx.fillText(
captchaText[i],
15 + i * 20,
30 + Math.random() * 10
);
}
// 绘制干扰线
for (let i = 0; i < 5; i++) {
ctx.strokeStyle = getRandomColor();
ctx.beginPath();
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.stroke();
}
return captchaText;
}
function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
后端验证的必要性
前端验证码容易被绕过,应结合后端验证:
- 服务端生成验证码文本并存储(如Session)
- 将验证码图像发送到客户端
- 用户提交后,服务端比对存储的验证码
Node.js示例:
// Express服务端示例
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 = generateRandomString();
req.session.captcha = captcha;
// 生成图像并发送
const canvas = createCanvas(150, 50);
// ...绘制验证码图像...
res.set('Content-Type', 'image/png');
canvas.pngStream().pipe(res);
});
app.post('/verify', (req, res) => {
if (req.body.captcha === req.session.captcha) {
res.send('验证成功');
} else {
res.status(400).send('验证码错误');
}
});
增强安全性的措施
- 限制验证码尝试次数
- 设置验证码有效期(通常2-5分钟)
- 使用更复杂的验证方式,如行为验证(拖动滑块、点击特定区域等)
- 定期更换验证码生成算法
使用第三方验证码服务
对于高安全性需求,可考虑专业验证码服务:
- Google reCAPTCHA
- hCaptcha
- 腾讯验证码
这些服务通常提供JavaScript集成方式,如reCAPTCHA v2:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="your-site-key"></div>
后端需验证返回的token:
const axios = require('axios');
async function verifyRecaptcha(token) {
const response = await axios.post(
'https://www.google.com/recaptcha/api/siteverify',
`secret=your-secret-key&response=${token}`
);
return response.data.success;
}






