需求
登录页面需要一个验证码,防止出现频繁“撞库”情况。
开发
安装
安装 svg-captcha 插件,实现 SVG 图片动态验证码。
npm i --save svg-captcha
配置
svg-captcha 不需要配置,但是因为牵扯到验证码校验时,需要将验证码共享到全局,方便其他位置的方法调用。
所以这里启用 session。(Ps:egg 框架自带 session,不需要额外安装)
// config.default.js
config.session = {
key: 'EGG_SESSION_KEY',
maxAge: 24 * 3600 * 1000, // 过期时间24小时
httpOnly: true, // 默认就是 true
encrypt: true, // 加密传输
renew: true //每次访问页面都会给session会话延长时间
}
后台
const {Service} = require('egg');
const svgCaptcha = require('svg-captcha');
class SystemService extends Service {
async login(params) {
const {ctx, app} = this;
// 校验验证码
if (params.verifyCode === ctx.session.verifyCode) {
ctx.state = 200;
ctx.body = {
code: 200,
success: true,
data: {token: 123},
msg: '登录成功',
show: true
}
} else {
ctx.body = {
code: 400,
success: false,
msg: '验证码错误',
show: true
}
}
}
async verifyCode() {
const {ctx, app} = this;
const verifyConfig = {
size: 5,
ignoreChars: '0oO1ilI', // 验证码字符中排除 0oO1ilI
noise: 3, // 干扰线条的数量
width: 176,
height: 40,
fontSize: 50,
color: true, // 验证码的字符是否有颜色,默认没有,如果设定了背景,则默认有
background: '#fff',
}
// 生成二维码svg
const captcha = svgCaptcha.create(verifyConfig);
// 验证码文字存放在 session 中(不区分大小写)
ctx.session.verifyCode = captcha.text.toLowerCase();
ctx.response.type = 'image/svg+xml';
ctx.body = {
code: 200,
success: true,
data: captcha.data,
msg: '验证码获取成功',
show: false
}
}
}
module.exports = SystemService;
前台
/** 刷新验证码 */
const reloadCaptcha = () => {
captcha().then(res => {
verifyImg.value = res.data;
});
}
<div class="verify-code" @click="reloadCaptcha">
<a-tooltip placement="right">
<template #title>点击刷新验证码</template>
<div v-html="verifyImg"></div>
</a-tooltip>
</div>
总结
验证码的实现借助插件还是比较简单的,但是对于 session 的认知和应用和后端人员还有较大差距,尤其对于 session & cookie 等方面需要加强。
如果自己做的系统对其他人开放的,在保证自己系统足够安全的情况下,我建议大家尽量不要增加验证码,减轻视障朋友们登录系统的负担。拙见~