您的博客内容很清晰,系统地介绍了svg-captcha模块的使用。我为您优化了代码结构和说明,使其更加专业和完善:
Node.js学习日志(6):svgCaptcha模块验证码生成
在用户登录或注册场景中,验证码是防止脚本批量操作的有效安全措施。svg-captcha模块能够生成SVG格式的验证码,具有无损缩放、文件体积小等优势。
模块安装
npm install svg-captcha
核心配置项说明
const svgCaptchaOptions = {
size: 6, // 验证码字符数量
ignoreChars: '0oOlIi1', // 排除易混淆字符
noise: 3, // 干扰线数量
color: true, // 彩色字符
background: '#f0f0f0', // 背景色
width: 150, // 图片宽度
height: 50, // 图片高度
fontSize: 50, // 字体大小
charPreset: 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ123456789', // 字符集
};
数字验证码实现
const svgCaptcha = require('svg-captcha');
const crypto = require('crypto');
function generateNumberCaptcha(options = {}) {
const defaultOptions = {
size: 6,
ignoreChars: '0oOlIi1',
noise: 2,
color: true,
background: '#f0f0f0',
width: 150,
height: 50
};
const captchaOptions = { ...defaultOptions, ...options };
const captcha = svgCaptcha.create(captchaOptions);
const captchaId = crypto.randomUUID();
return {
id: captchaId,
data: captcha.data, // SVG图像数据
text: captcha.text, // 验证码文本(服务端存储)
timestamp: Date.now() // 生成时间戳
};
}
// 使用示例
const numberCaptcha = generateNumberCaptcha();
console.log('数字验证码:', numberCaptcha.text);
算式验证码实现
function generateMathCaptcha(options = {}) {
const defaultOptions = {
noise: 1,
color: true,
background: '#f0f0f0',
width: 150,
height: 50
};
const captchaOptions = { ...defaultOptions, ...options };
const captcha = svgCaptcha.createMathExpr(captchaOptions);
const captchaId = crypto.randomUUID();
return {
id: captchaId,
data: captcha.data, // SVG图像数据
text: captcha.text, // 算式计算结果(服务端存储)
timestamp: Date.now() // 生成时间戳
};
}
// 使用示例
const mathCaptcha = generateMathCaptcha();
console.log('算式验证码结果:', mathCaptcha.text);
Express.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/number', (req, res) => {
const captcha = generateNumberCaptcha();
req.session.captcha = {
id: captcha.id,
text: captcha.text,
expires: Date.now() + 10 * 60 * 1000 // 10分钟有效期
};
res.type('svg');
res.send(captcha.data);
});
// 获取算式验证码
app.get('/captcha/math', (req, res) => {
const captcha = generateMathCaptcha();
req.session.captcha = {
id: captcha.id,
text: captcha.text,
expires: Date.now() + 10 * 60 * 1000
};
res.type('svg');
res.send(captcha.data);
});
// 验证码验证接口
app.post('/verify', express.json(), (req, res) => {
const { captchaText } = req.body;
const storedCaptcha = req.session.captcha;
if (!storedCaptcha || Date.now() > storedCaptcha.expires) {
return res.json({ success: false, message: '验证码已过期' });
}
if (captchaText.toLowerCase() === storedCaptcha.text.toLowerCase()) {
delete req.session.captcha; // 验证成功后清除
return res.json({ success: true, message: '验证成功' });
} else {
return res.json({ success: false, message: '验证码错误' });
}
});
app.listen(3000, () => {
console.log('服务器运行在端口3000');
});

被折叠的 条评论
为什么被折叠?



