1.安装svg-captcha
npm install --save svg-captcha
2.安装egg-session-redis
使session存储到redis中
npm i egg-session-redis egg-redis --save
3.开启egg-session-redis
config/plugin.ts
// 开启sessionRedis 使session存储到 redis 中
sessionRedis: {
enable: true,
package: 'egg-session-redis',
},
redis: {
enable: true,
package: 'egg-redis',
},
4.配置redis
config/config.local.ts开发阶段
// 配置Redis
config.redis = {
client: {
host: '127.0.0.1',//ip
port: 6379,//端口号
password: '',//密码
db: 0,//数据库
},
agent: true,
};
5.在app目录下创建util目录并创建imageCode.ts
import svgCaptcha = require('svg-captcha');
export default {
//创建验证码
createImageCode(ctx) {
// 1.生成验证码
// c= {text:验证码字符串,data:验证码svg图片}
const c = svgCaptcha.create({
size: 4, // 验证码长度
width: 160, // 验证码图片宽度
height: 60, // 验证码图片高度
fontSize: 50, // 验证码文字大小
ignoreChars: '0oO1ilI', // 验证码字符中排除内容 0o1i
noise: 4, // 干扰线条的数量
color: true, // 验证码的字符是否有颜色,默认没有,如果设定了背景,则默认有
background: '#eee', // 验证码图片背景颜色
});
console.log(c.text);
// 2.保存生成的验证码
ctx.session.captcha = {
code: c.text,
expire: Date.now() + 60 * 1000, // 一分钟后过期
};
return c.data;
},
//验证验证码
verifyImageCode(ctx, clientCode) {
// 1.取出服务端中保存的验证码和过期时间
const serverCaptcha = ctx.session.captcha;
let serverCode;
let serverExpire;
try {
serverCode = serverCaptcha.code;
serverExpire = serverCaptcha.expire;
} catch (e) {
// 验证码无论验证成功还是失败,都只能使用一次 提高安全性
ctx.session.captcha = null;
throw new Error('请重新获取验证码');
}
// 2.获得客户端传递过来的验证码
if (Date.now() > serverExpire) {
// 验证码无论验证成功还是失败,都只能使用一次 提高安全性
ctx.session.captcha = null;
throw new Error('验证码已经过期');
} else if (serverCode !== clientCode) {
// 验证码无论验证成功还是失败,都只能使用一次 提高安全性
ctx.session.captcha = null;
throw new Error('验证码不正确');
}
// 验证码无论验证成功还是失败,都只能使用一次 提高安全性
ctx.session.captcha = null;
},
};
6.在app/extend创建helper.ts
import ImageCode from '../util/imageCode';
module.exports = {
createImageCode() {
return ImageCode.createImageCode(this.ctx);
},
verifyImageCode(clientCode) {
ImageCode.verifyImageCode(this.ctx, clientCode);
},
};
7.在app/controller目录下创建util.ts
import { Controller } from 'egg';
export default class UtilController extends Controller {
public async imageCode() {
const { ctx } = this;
ctx.body = ctx.helper.createImageCode();
}
}
8.在app/router.ts添加创建验证码路由
router.get('/imagecode', controller.util.imageCode);
9.用户进行用户名密码注册的时候验证验证码是否正确
user.ts
switch (registerType) {
case RegisterTypeEnum.Normal:
// 校验数据的格式是否正确
ctx.validate(NormalUserRule, data);
// 校验验证码是否正确
ctx.helper.verifyImageCode(data.captcha);
break;