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("驗證碼不正確"); }