框架引入,需要引入驗證碼框架和郵箱服務框架,用Springboot整合所以帶有stater,郵箱注冊需要防止盜刷,所以需要引入驗證碼框架,需要防止多次請求,所以選用redis
<dependency> <groupId>com.baomidou</groupId> <artifactId>kaptcha-spring-boot-starter</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>2.3.3.RELEASE</version> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
jedis性能比RedisTemplate的性能好3倍,並且隨着數據量的增大,倍數也成指數增加
因此優先選擇jedis
,因為他在性能方面完勝RedisTemplate
郵箱服務配置,通過網易申請申請得到,一些郵箱相關的信息,配置Application文件
spring: mail: host: smtp.126.com //發送郵件服務器 username: xxxx@126.com //郵箱 password: xxxxxxx //客戶端授權碼 千萬注意這個不是密碼 是客戶端授權碼 from: xxxx@126.com // properties.mail.smtp.starttls.enable: true properties.mail.smtp.starttls.required: true properties.mail.smtp.ssl.enable: true //開啟ssl default-encoding: utf-8 //編碼utf-8
redis:
host: xxx.xxx.xxx.xxx
port: xxxx
password: xxxx
驗證碼的配置
@Configuration public class CaptchaConfig { @Bean @Qualifier("captchaProducer") //重新命名Bean public DefaultKaptcha defaultKaptcha(){ 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; } }
發送驗證碼,防止重復請求驗證碼
public JsonData sendCode(SendCodeEnum sendCodeEnum, String to) { String cacheKey = String.format(CacheKey.CHECK_CODE_KEY,sendCodeEnum.name(),to); String cacheValue = redisTemplate.opsForValue().get(cacheKey); log.info(cacheValue);
//二次進入 if(cacheValue!=null){ long ttl =Long.parseLong(cacheValue.split("_")[1]); if(CommonUtil.getCurrentTimestamp()-ttl<1000*60){ log.info("重復發送驗證碼,時間間隔為:{}秒",(CommonUtil.getCurrentTimestamp()-ttl)/1000); return JsonData.buildResult(BizCodeEnum.CODE_LIMITED); } } String code = CommonUtil.getRandomCode(6); String value = code +"_" +CommonUtil.getCurrentTimestamp(); redisTemplate.opsForValue().set(cacheKey,value,CODE_EXPIRED, TimeUnit.MILLISECONDS); if(CheckUtils.isEmail(to)){ mailService.sendEmail(to,SUBJECT,String.format(CONTENT,code)); return JsonData.buildSuccess(); }else if(CheckUtils.isPhone(to)) { } return JsonData.buildSuccess(); }
注冊功能
public JsonData register(UserRegisterRequest registerRequest) { boolean checkCode= false; if( registerRequest.getMail()!=null){ checkCode = notifyService.checkCode(SendCodeEnum.USER_REGISTER,registerRequest.getMail(),registerRequest.getCode()); } if(!checkCode){ return JsonData.buildResult(BizCodeEnum.CODE_ERROR); } UserDO userDO = new UserDO(); BeanUtils.copyProperties(registerRequest,userDO); userDO.setCreateTime(new Date()); userDO.setSlogan("xxxxx"); userDO.setSecret("$1$"+ CommonUtil.getRandomCode(8)); String cryPwd= CommonUtil.MD5(registerRequest.getPwd()+userDO.getSecret()); userDO.setPwd(cryPwd); if(checkUnique(userDO.getMail())){ int rows =userMapper.insert(userDO); log.info("rows={},注冊成功:{}",rows,userDO.toString()); return JsonData.buildSuccess(); }else{ return JsonData.buildResult(BizCodeEnum.ACCOUNT_REPEAT); } }
controller層
@Autowired private Producer captchaProducer; @Autowired private StringRedisTemplate redisTemplate; @Autowired NotifyService notifyService; private static final long CAPTCHA_CODE_EXPIRED= 60*1000*10; @GetMapping("captcha") public void getCaptcha(HttpServletRequest request, HttpServletResponse response){ String captchaText=captchaProducer.createText(); log.info("圖形驗證碼:{}",captchaText); redisTemplate.opsForValue().set(getCaptchaKey(request),captchaText,CAPTCHA_CODE_EXPIRED, TimeUnit.MILLISECONDS); BufferedImage bufferedImage = captchaProducer.createImage(captchaText); ServletOutputStream outputStream =null; try{ outputStream =response.getOutputStream(); ImageIO.write(bufferedImage,"jpg",outputStream); outputStream.flush(); outputStream.close(); }catch (IOException e){ log.error("獲取圖形驗證碼異常{}",e); } } @GetMapping("send_code") public JsonData sendRegisterCode(@RequestParam(value="to",required = true) String to, @RequestParam(value = "captcha",required = true) String captcha,HttpServletRequest request){ String key = getCaptchaKey(request); String cacheCaptcha =redisTemplate.opsForValue().get(key); log.info("heheee"); if(captcha!=null &&captcha!=null &&captcha.equalsIgnoreCase(cacheCaptcha)){ redisTemplate.delete(key); JsonData jsonData = notifyService.sendCode(SendCodeEnum.USER_REGISTER,to); return jsonData; }else{ return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR); } } private String getCaptchaKey(HttpServletRequest request){ String ip= CommonUtil.getIpAddr(request); String userAgent=request.getHeader("User-Agent"); String key="user-service:captcha"+ip+CommonUtil.MD5(ip+userAgent); log.info("ip= {}",ip); log.info("userAgent={}",userAgent); log.info("key={}",key); return key; }
郵箱代碼編寫
@Service @Slf4j public class MailServiceImpl implements MailService { @Autowired JavaMailSender javaMailSender; @Value("${spring.mail.from}") private String from; @Override public void sendEmail(String to,String subject,String content) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(from); message.setTo(to); message.setSubject(subject); message.setText(content); javaMailSender.send(message); log.info( "郵箱發送成功 {}",message); } }
后端測試結果
總結:redis 首先存儲 map<key,value> 首先是 <user-service:captcha:ip+md5(ip+ugent),圖形驗證碼> 然后是map<code:%s:%s,郵箱驗證碼+當前時間軸> 第一個%s是USER_REGISTER,第二個是要發送的郵箱
代碼百度雲: 把application文件刪除 需要自己配置數據庫 redis mail
鏈接:https://pan.baidu.com/s/1ejwAQ-MnmJGhakXouscXKA
提取碼:gcwu
--來自百度網盤超級會員V4的分享
歡迎討論 +Q3378404370