365彩票官方正版下载

图形验证码使用全解析,提升系统安全性的必备技巧

图形验证码使用全解析,提升系统安全性的必备技巧

为了更加方便的使用aj-captcha验证码功能,本人将此项目集成到了大麦网项目中,作为基础组件来使用,并且将验证码缓存的方式修改成了改为redis来存储,因为在生产环境服务多实例情况下,使用本地缓存肯定是不行的

模块:damai-captcha-framework

com.example

damai-captcha-framework

${revision}

组件保留了aj-captcha的所有验证功能,并且提供了获取验证码和校验验证码的api,可以根据业务需求来灵活使用

讲解

验证码缓存方式

首先我们看下aj-captcha中是怎么进行加载缓存数据的

Springboot3方式

org.springframework.boot.autoconfigure.AutoConfiguration.imports

com.damai.config.AjCaptchaAutoConfiguration

com.damai.config.CaptchaAutoConfig

Springboot2方式

spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.anji.captcha.config.AjCaptchaAutoConfiguration

使用了springboot的自动装配功能

AjCaptchaAutoConfiguration

@Configuration

@EnableConfigurationProperties(AjCaptchaProperties.class)

@ComponentScan("com.anji.captcha")

@Import({AjCaptchaServiceAutoConfiguration.class, AjCaptchaStorageAutoConfiguration.class})

public class AjCaptchaAutoConfiguration {

}

AjCaptchaStorageAutoConfiguration就是缓存数据的配置

@Configuration

public class AjCaptchaStorageAutoConfiguration {

@Bean(name = "AjCaptchaCacheService")

public CaptchaCacheService captchaCacheService(AjCaptchaProperties ajCaptchaProperties){

//缓存类型redis/local/....

return CaptchaServiceFactory.getCache(ajCaptchaProperties.getCacheType().name());

}

}

能够看到是通过ajCaptchaProperties.getCacheType().name()属性从CaptchaServiceFactory工厂中获取

属性通过aj.captcha.cache-type来配置

下面来分析下CaptchaServiceFactory工厂的加载流程

public static CaptchaCacheService getCache(String cacheType) {

return cacheService.get(cacheType);

}

public volatile static Map instances = new HashMap();

public volatile static Map cacheService = new HashMap();

static {

ServiceLoader cacheServices = ServiceLoader.load(CaptchaCacheService.class);

for (CaptchaCacheService item : cacheServices) {

cacheService.put(item.type(), item);

}

logger.info("supported-captchaCache-service:{}", cacheService.keySet().toString());

ServiceLoader services = ServiceLoader.load(CaptchaService.class);

for (CaptchaService item : services) {

instances.put(item.captchaType(), item);

}

;

logger.info("supported-captchaTypes-service:{}", instances.keySet().toString());

}

cacheService中存在的就是缓存处理类,key为类型, value为CaptchaCacheService的实现类

spring启动后,会执行被@Bean修饰的captchaCacheService方法

当CaptchaServiceFactory的getCache方法时,会加载CaptchaServiceFactory类,从而加载static静态块

通过java spi机制扫描出CaptchaCacheService的实现类,然后添加到cacheService中

这时调用CaptchaServiceFactory的getCache方法时,就会根据缓存类型从cacheService中取出

在aj-captcha中,默认的缓存策略使用的是本地缓存

private StorageType cacheType = local;

CaptchaCacheServiceMemImpl就是本地缓存策略的实现

/**

* 对于分布式部署的应用,我们建议应用自己实现CaptchaCacheService,比如用Redis,参考service/spring-boot代码示例。

* 如果应用是单点的,也没有使用redis,那默认使用内存。

* 内存缓存只适合单节点部署的应用,否则验证码生产与验证在节点之间信息不同步,导致失败。

* @Title: 默认使用内存当缓存

* @author lide1202@hotmail.com

* @date 2020-05-12

*/

public class CaptchaCacheServiceMemImpl implements CaptchaCacheService {

@Override

public void set(String key, String value, long expiresInSeconds) {

CacheUtil.set(key, value, expiresInSeconds);

}

@Override

public boolean exists(String key) {

return CacheUtil.exists(key);

}

@Override

public void delete(String key) {

CacheUtil.delete(key);

}

@Override

public String get(String key) {

return CacheUtil.get(key);

}

@Override

public Long increment(String key, long val) {

Long ret = Long.valueOf(CacheUtil.get(key))+val;

CacheUtil.set(key,ret+"",0);

return ret;

}

@Override

public String type() {

return "local";

}

}

在生产中高并发的项目肯定都是多实例部署的,所以本地缓存这种方式肯定不行,我们改用redis的方式

使用redis我们要借助springboot提供的redis操作StringRedisTemplate

但要注意,这里缓存策略的实现都是用的java spi加载得到的,而且并没有被spring管理,所以直接通过构造器注入StringRedisTemplate是不行的,需要主动调用方法来进行注入,下面介绍如何改用redis的保存方式

相关推荐

《魔兽世界》尼奥罗萨觉醒之城入口位置
365bet手机版

《魔兽世界》尼奥罗萨觉醒之城入口位置

📅 2025-08-11 👁️ 3341
软炸麻花在家做,蓬松香软皮酥脆,好吃不腻,比卖的简单还好吃
教你简单纸做菊花
365体育官网贴吧

教你简单纸做菊花

📅 2025-09-14 👁️ 3648
富士HS11评测:局部细节 机身做工
365彩票官方正版下载

富士HS11评测:局部细节 机身做工

📅 2025-08-10 👁️ 2505