一起做网站可以一件代发吗,泰安网站建设费用,织梦cms官网模板,seo网络营销推广优化登录验证码高扩展性建设方案
本文分享了一种登录验证码高扩展性的建设方案#xff0c;通过工厂模式策略模式#xff0c;增强了验证码服务中验证码生成器、验证码存储器、验证码图片生成器的扩展性#xff0c;实现了服务组件的多样化#xff0c;降低了维护成本 登录验证码高…登录验证码高扩展性建设方案
本文分享了一种登录验证码高扩展性的建设方案通过工厂模式策略模式增强了验证码服务中验证码生成器、验证码存储器、验证码图片生成器的扩展性实现了服务组件的多样化降低了维护成本 登录验证码高扩展性建设方案1、前言2、接口规范3、流程规范4、验证码的实际开发示范5、总结 1、前言
在进行登录时无论是账号密码登录还是第三方登录总是需要输入验证码。
使用验证码可以进行人机判断提高安全性过滤恶性攻击。
验证码一般由一串随机字符组成当然也存在多种生成方式。
验证码的展现方式有很多种例如图片语音手机验证码。
验证码的存储方式有很多种例如数据库、缓存、JVM本地内存。
验证码的存储又涉及到另一个问题验证码唯一id如何生成在分布式项目中一般可以通过数据库自增序列、缓存自增序列、UUID、雪花算法等方式生成唯一id。
既然生成一个验证码有这么多种方法那如何设计一种高扩展性的验证码服务架构使得各个部分的组件可以自由替换呢这就是本文需要解决的问题。
技术栈SpringBootMySQLRediszookeeper。
设计模式策略模式。
2、接口规范
根据上述分析我们需要分别实现验证码的生成、展示、id生成、存储的接口一般验证码服务需要对外提供生成验证码和校验验证码的api我们写在一个接口中四个组件以内部接口类的形式进行开发。 /*** version 1.0* description 验证码接口* date 2023/9/29 15:59*/
public interface CheckCodeService {// 生成验证码public CheckCodeResultDto generate(CheckCodeParamsDto checkCodeParamsDto);// 校验验证码public boolean verify(String key, String code);// 验证码生成器public interface CheckCodeGenerator{String generate(int length);}// 唯一id生成public interface KeyGenerator{String generate(String prefix);}// 验证码存储器public interface CheckCodeStore{void set(String key, String value, Integer expire);String get(String key);void remove(String key);}// 展示包装器public interface DisplayGenerate{String display(String code);}
}
3、流程规范
定义好接口规范后我们需要对流程进行规范正常流程是使用验证码生成器生成一个随机的验证码使用id生成器生成一个唯一id使用存储器存储验证码和id以不同的展示方式包装验证码并返回。
此时我们还没有实际开发各个生成器模块只是对流程进行规范让不同的展示方法代码实现我们这个规范所以这个应该通过抽象类的方式实现各个生成器模块以注入的方式得到。 /*** version 1.0* description 验证码接口* date 2023/9/29 15:59*/
public abstract class AbstractCheckCodeService implements CheckCodeService {// 验证码生成器protected CheckCodeGenerator checkCodeGenerator;// id生成器protected KeyGenerator keyGenerator;// 验证码存储器protected CheckCodeStore checkCodeStore;// 展示包装器protected DisplayGenerate displayGenerator;public abstract void setCheckCodeGenerator(CheckCodeGenerator checkCodeGenerator);public abstract void setKeyGenerator(KeyGenerator keyGenerator);public abstract void setCheckCodeStore(CheckCodeStore CheckCodeStore);public abstract void setDisplayGenerate(DisplayGenerate displayGenerate);// 生成验证码public GenerateResult generate(CheckCodeParamsDto checkCodeParamsDto,Integer code_length,String keyPrefix,Integer expire){//生成验证码String code checkCodeGenerator.generate(code_length);//生成唯一idString key keyGenerator.generate(keyPrefix);//存储验证码checkCodeStore.set(key,code,expire);//验证码展示方法String display displayGenerator.display(code);//返回验证码生成结果GenerateResult generateResult new GenerateResult();generateResult.setKey(key);generateResult.setCode(code);generateResult.setDisplay(display);return generateResult;}Dataprotected class GenerateResult{String key;String code;String display;}public abstract CheckCodeResultDto generate(CheckCodeParamsDto checkCodeParamsDto);// 校验验证码public boolean verify(String key, String code){if (StringUtils.isBlank(key) || StringUtils.isBlank(code)){return false;}String code_l checkCodeStore.get(key);if (code_l null){return false;}boolean result code_l.equalsIgnoreCase(code);if(result){//删除验证码checkCodeStore.remove(key);}return result;}
}
参数类 public class CheckCodeParamsDto {// 验证码展示类型private String checkCodeType;
}
4、验证码的实际开发示范
实际实现抽象类的方法需要完成四个组件的注入即可。 Service(CheckCodeService)
public class CheckCodeServiceImpl extends AbstractCheckCodeService implements CheckCodeService {Resource(nameNumberLetterCheckCodeGenerator)Overridepublic void setCheckCodeGenerator(CheckCodeGenerator checkCodeGenerator) {this.checkCodeGenerator checkCodeGenerator;}Resource(nameUUIDKeyGenerator)Overridepublic void setKeyGenerator(KeyGenerator keyGenerator) {this.keyGenerator keyGenerator;}Resource(nameMemoryCheckCodeStore)Overridepublic void setCheckCodeStore(CheckCodeStore checkCodeStore) {this.checkCodeStore checkCodeStore;}Resource(namePicCheckCodeGenerator)Overridepublic void setDisplayGenerate(DisplayGenerator displayGenerator) {this.displayGenerator displayGenerator;}Overridepublic CheckCodeResultDto generate(CheckCodeParamsDto checkCodeParamsDto) {GenerateResult generate generate(checkCodeParamsDto, 4, checkcode:, 60);String key generate.getKey();String code generate.getCode();String display generate.getDisplay();CheckCodeResultDto checkCodeResultDto new CheckCodeResultDto();checkCodeResultDto.setDisplay(display);checkCodeResultDto.setKey(key);return checkCodeResultDto;}}涉及的实体类 /*** version 1.0* description 验证码生成结果类* date 2023/9/29 15:48*/
Data
public class CheckCodeResultDto {// 验证码idprivate String key;// 展示方式private String display;
}
四个组件的实现示范
验证码生成器 Component(NumberLetterCheckCodeGenerator)
public class NumberLetterCheckCodeGenerator implements CheckCodeService.CheckCodeGenerator {Overridepublic String generate(int length) {String strABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;Random randomnew Random();StringBuffer sbnew StringBuffer();for(int i0;ilength;i){int numberrandom.nextInt(36);sb.append(str.charAt(number));}return sb.toString();}
}
唯一id生成器以UUID的方式生成 Component(UUIDKeyGenerator)
public class UUIDKeyGenerator implements CheckCodeService.KeyGenerator {Overridepublic String generate(String prefix) {String uuid UUID.randomUUID().toString();return prefix uuid.replaceAll(-, );}
}
验证码存储器以Redis为例 Component(MemoryCheckCodeStore)
public class MemoryCheckCodeStore implements CheckCodeService.CheckCodeStore {Autowiredpublic RedissonClient redissonClient;Overridepublic void set(String key, String value, Integer expire) {if (get(key)!null) log.error(codes key conflict);redisTemplate.opsForValue().set(key, value, 300 new Random().nextInt(100), TimeUnit.SECONDS);}Overridepublic String get(String key) {return (String) redisTemplate.opsForValue().get(key);}Overridepublic void remove(String key) {boolean b redisTemplate.opsForValue().getOperations().delete(key);if (!b) log.info(remove codes key failure);}
}
展示生成器以图片为例 Component(PicCheckCodeGenerate)
public class PicCheckCodeGenerate implements CheckCodeService.DisplayGenerate {Autowiredprivate DefaultKaptcha kaptcha;Overrideprivate String display(String code) {// 生成图片验证码ByteArrayOutputStream outputStream null;BufferedImage image kaptcha.createImage(code);outputStream new ByteArrayOutputStream();String imgBase64Encoder null;try {// 对字节数组Base64编码BASE64Encoder base64Encoder new BASE64Encoder();ImageIO.write(image, png, outputStream);imgBase64Encoder data:image/png;base64, EncryptUtil.encodeBase64(outputStream.toByteArray());} catch (IOException e) {e.printStackTrace();} finally {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}return imgBase64Encoder;}
}5、总结
本文针对验证码生成过程节点多、实现方案多等特点提出了一种高扩展性的建设方案并给出了实际开发示例。
本文提出的验证码生成框架具有高扩展性可以对任一组件进行创建开发、动态替换。如果结合Nacos和yaml还可以实现组件热更新。