UID是唯一标识的字符串,下面是百度百科关于UUID的定义:
UUID是由一组32位数的16进制数字所构成,是故UUID理论上的总数为1632=2128,约等于3.4 x 10^38。也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID用完。
UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符。示例:
550e8400-e29b-41d4-a716-446655440000
具体流程:
点击这个框,前端会生成一个UUID(这里是前端生成UUID的情况),
并且把这个UUID发送给后端,然后后端得到这个UUID后,后端自己再通过算法随机生成5位验证码字符串(比如上图的4xb22,这时候只是一串字符串)(如果UUID不是前端生成的,后端这时候也一起生成UUID)。
然后后端将这个字符串验证码和得到的UUID进行绑定(也就是说有这个UUID就能得到验证码字符串,可以理解是 key: “UUID”,value: “验证码字符串”)。
然后后端再通过其他算法(图像生成算法)将这个验证码字符串渲染成验证码图片。这时候,把这个图片发送给前端,后端在数据库中保存UUID和验证码字符串以及有效时间。
我们回到前端,当前端得到后端给的验证码图片后,显示在验证码该显示的地方。
然后用户开始输入验证码,当用户点击登录的时候,又发一次请求给后端,这个请求带有账号密码等信息,最重要的是,它还将UUID,和用户输入的验证码传给了后端。
然后后端拿到这些信息(UUID,验证码)后,就把这个UUID拿去查询它对应的字符串(K,V),将这个后端保存的验证码和前端发送来的验证码进行对比,如果对了,就验证成功,如果错了,就验证失败。
接口实习代码:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_captcha")
@ApiModel(value = "SysCaptcha对象", description = "系统验证码")
public class SysCaptcha implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "uuid")@TableId(value = "uuid", type = IdType.ID_WORKER)private String uuid;@ApiModelProperty(value = "验证码")private String code;@ApiModelProperty(value = "过期时间")private Date expireTime;}
@GetMapping("captcha.jpg")public void captcha(HttpServletResponse response, String uuid) throws IOException {try {response.setHeader("Cache-Control", "no-store, no-cache");response.setContentType("image/jpeg");//获取图片验证码BufferedImage image = sysCaptchaService.getCaptcha(uuid);ServletOutputStream out = response.getOutputStream();ImageIO.write(image, "jpg", out);IOUtils.closeQuietly(out);} catch (Exception e) {// 重置responseresponse.reset();response.setContentType("application/json");response.setCharacterEncoding("utf-8");Map<String, Object> map = MapUtils.newHashMap();map.put("code", 400);map.put("msg", "验证码加载失败");log.error("验证码加载失败:", e);response.getWriter().println(JSON.toJSONString(map));}}
public interface SysCaptchaService extends IService<SysCaptcha> {/*** 获取图片验证码*/BufferedImage getCaptcha(String uuid);/*** 验证码效验* @param uuid uuid* @param code 验证码* @return true:成功 false:失败*/boolean validate(String uuid, String code);
}import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.code.kaptcha.Producer;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.awt.image.BufferedImage;
import java.util.Date;@Service
public class SysCaptchaServiceImpl extends ServiceImpl<SysCaptchaMapper, SysCaptcha>implements SysCaptchaService {@Autowiredprivate Producer producer;@Overridepublic BufferedImage getCaptcha(String uuid) {if (StringUtils.isBlank(uuid)) {throw new ApiException("uuid不能为空");}//生成文字验证码String code = producer.createText();SysCaptcha captchaEntity = new SysCaptcha();captchaEntity.setUuid(uuid);captchaEntity.setCode(code);//5分钟后过期captchaEntity.setExpireTime(DateTimeUtils.addDateMinutes(new Date(), 5));this.save(captchaEntity);return producer.createImage(code);}@Overridepublic boolean validate(String uuid, String code) {SysCaptcha captchaEntity = this.getOne(new QueryWrapper<SysCaptcha>().eq("uuid", uuid));if (captchaEntity == null) {return false;}//删除验证码this.removeById(uuid);if (captchaEntity.getCode().equalsIgnoreCase(code)&& captchaEntity.getExpireTime().getTime() >= System.currentTimeMillis()) {return true;}return false;}
}
boolean captcha = sysCaptchaService.validate(userLoginRequest.getUuid(),userLoginRequest.getCaptcha());
if (!captcha) {return BaseResult.fail("验证码不正确"); }