1、问题的提出
在以前的基于短信验证码的登录接口设计完成之后会有一定的安全性问题,例如攻击者会对短信验证码的接口进行不断的调用,这对于公司的短信流量是一个巨大的损耗,同时对于公司的流量带宽也会有很大的影响。
2、解决方案
使用图像验证码或者窗口验证的方式解决该问题,具体的设计思路是在发送短信验证码之前加图形验证码或者滑动窗口,这里我们采取的是加图形验证码的解决方案。
图形验证码采用的是Google的kaptcha图形库,我们先配置图形验证码的bean对象,在生成图形验证码通过ImageIO技术网络传输。
@Bean
@Qualifier("captchaProducer")
public DefaultKaptcha kaptcha() {
DefaultKaptcha kaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
// properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "220,220,220");
// //properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "38,29,12");
// properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "147");
// properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "34");
// properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "25");
// //properties.setProperty(Constants.KAPTCHA_SESSION_KEY, "code");
//验证码个数
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Courier");
//字体间隔
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,"8");
//干扰线颜色
// properties.setProperty(Constants.KAPTCHA_NOISE_COLOR, "white");
//干扰实现类
properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
//图片样式
properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.WaterRipple");
//文字来源
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789");
Config config = new Config(properties);
kaptcha.setConfig(config);
return kaptcha;
}
3、关于验证码60秒之内不可重复发送的解决方案
验证码60s之内不可重复发送可以由前端来做校验,但对于知道后端接口地址的话可以跳过前端的校验,因此,系统还是不安全的。因此我们要在后端还要做校验功能。
我们通过对redis验证码的值加时间戳的方法来解决这个问题,我们发送验证码的时候去redis里面查一查是否存了同一账号发送的验证码,如果存了在进行时间戳的比较,如果时间没有超过60s则退出,超过60s则重新发送。