一、效果
使用hutool captcha實現簡單的圖形驗證碼,可以參考官網概述 | Hutool
?二、實現步驟
1、導入依賴
<!--hutool包-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version>
</dependency>
2、后端代碼
@RestController
@RequestMapping()
public class CaptchaController {private static final String REDIS_KEY = "captcha";@Autowiredprivate RedisTemplate redisTemplate;@GetMapping("/lineCaptcha")public Result createLineCaptcha() {//創建一個線性驗證碼圖片,并將其輸出到瀏覽器LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 40, 4, 9);//設置驗證碼內容,并輸出到瀏覽器String code = lineCaptcha.getCode();//redis存儲驗證碼內容//設置驗證碼有效期為1分鐘redisTemplate.opsForValue().set(REDIS_KEY, code, 60, TimeUnit.SECONDS);//獲取驗證碼圖片的Base64編碼數據String imageBase64Data = lineCaptcha.getImageBase64Data();
// // 設置正確的 MIME 類型
// response.setContentType("image/png");
// lineCaptcha.write(response.getOutputStream());
// //將驗證碼內容保存到響應頭中,供客戶端驗證使用
// response.setHeader("REDIS_KEY", code);return Result.success(imageBase64Data);}@GetMapping("/circleCaptcha")public Result createCircleCaptcha() {CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(100, 40, 4, 9);String code = circleCaptcha.getCode();//redis存儲驗證碼內容//設置驗證碼有效期為1分鐘redisTemplate.opsForValue().set(REDIS_KEY, code, 60, TimeUnit.SECONDS);//獲取驗證碼圖片的Base64編碼數據String imageBase64Data = circleCaptcha.getImageBase64Data();return Result.success(imageBase64Data);}@GetMapping("/shearCaptcha")public Result createShearCaptcha() {ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(100, 40, 4, 9);String code = shearCaptcha.getCode();//redis存儲驗證碼內容//設置驗證碼有效期為1分鐘redisTemplate.opsForValue().set(REDIS_KEY, code, 60, TimeUnit.SECONDS);//獲取驗證碼圖片的Base64編碼數據String imageBase64Data = shearCaptcha.getImageBase64Data();return Result.success(imageBase64Data);}@GetMapping("/gifCaptcha")public Result createGifCaptcha() {GifCaptcha gifCaptcha = CaptchaUtil.createGifCaptcha(100, 40, 4);//redis存儲驗證碼內容String code = gifCaptcha.getCode();//設置驗證碼有效期為1分鐘redisTemplate.opsForValue().set(REDIS_KEY, code, 60, TimeUnit.SECONDS);//獲取驗證碼圖片的Base64編碼數據String imageBase64Data = gifCaptcha.getImageBase64Data();return Result.success(imageBase64Data);}@GetMapping("/diyCharCaptcha")public Result createDiyCharCaptcha() {// 定義圖形驗證碼的長、寬、驗證碼字符數、干擾線寬度//ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(100, 40, 4, 4);LineCaptcha captcha = CaptchaUtil.createLineCaptcha(100, 40, 4, 4);// 自定義純數字的驗證碼(隨機4位數字,可重復)RandomGenerator randomGenerator = new RandomGenerator("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 4);// 自定義驗證碼內容為隨機4位字符captcha.setGenerator(randomGenerator);//redis存儲驗證碼內容String code = captcha.getCode();System.out.println("隨機4位字符驗證碼:" + code);String imageBase64Data = captcha.getImageBase64Data();return Result.success(imageBase64Data);}@GetMapping("/diyComputeCaptcha")public Result createDiyComputeCaptcha() {// 定義圖形驗證碼的長、寬、驗證碼字符數、干擾線寬度LineCaptcha captcha = CaptchaUtil.createLineCaptcha(100, 40, 4, 4);/*** 自定義驗證碼內容為四則運算方式* numberLength默認為2,即生成的計算式為兩個兩位數的計算 88+11=*/MathGenerator mathGenerator = new MathGenerator(1);captcha.setGenerator(mathGenerator);//redis存儲驗證碼內容String code = captcha.getCode();System.out.println("四則運算驗證碼:" + code);// 驗證用戶輸入是否正確String userInputCode = "10";boolean isCorrect = mathGenerator.verify(code, userInputCode);System.out.println("用戶輸入:" + userInputCode + ",是否正確:" + isCorrect);String imageBase64Data = captcha.getImageBase64Data();return Result.success(imageBase64Data);}
}
?3、前端代碼
api
import request from "@/utils/request";/*** 獲取驗證碼** @returns 驗證碼圖片*/
export const getLineCaptcha = () => {return request({url: "/lineCaptcha",method: "get",// responseType: "blob",});
};
export const getCircleCaptcha = () => {return request({url: "/circleCaptcha",method: "get",});
};
export const getShearCaptcha = () => {return request({url: "/shearCaptcha",method: "get",});
};
export const getGifCaptcha = () => {return request({url: "/gifCaptcha",method: "get",});
};
export const getDiyCharCaptcha = () => {return request({url: "/diyCharCaptcha",method: "get",});
};
export const getDiyComputeCaptcha = () => {return request({url: "/diyComputeCaptcha",method: "get",});
};
vue頁面
<template><div class="captcha"><h1>驗證碼</h1><div class="hutoll"><h3>hutool工具</h3><span>LineCaptcha:<img :src="LineCaptcha" alt="驗證碼" @click="changeCaptchaImg('Line')"/></span><span>CircleCaptcha:<img:src="CircleCaptcha"alt="驗證碼"@click="changeCaptchaImg('Circle')"/></span><span>ShearCaptcha:<img:src="ShearCaptcha"alt="驗證碼"@click="changeCaptchaImg('Shear')"/></span><span>GifCaptcha:<img :src="GifCaptcha" alt="驗證碼" @click="changeCaptchaImg('Gif')"/></span><span>DiyCharCaptcha:<img:src="DiyCharCaptcha"alt="驗證碼"@click="changeCaptchaImg('DiyChar')"/></span><span>DiyComputeCaptcha:<img:src="DiyComputeCaptcha"alt="驗證碼"@click="changeCaptchaImg('DiyCompute')"/></span></div></div>
</template><script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import {getLineCaptcha,getCircleCaptcha,getShearCaptcha,getGifCaptcha,getDiyCharCaptcha,getDiyComputeCaptcha,} from "@/api/captcha/index";
import { ElMessage } from "element-plus";const LineCaptcha = ref("");
const CircleCaptcha = ref("");
const ShearCaptcha = ref("");
const GifCaptcha = ref("");
const DiyCharCaptcha = ref("");
const DiyComputeCaptcha = ref("");const captchaRefs = {Line: LineCaptcha,Circle: CircleCaptcha,Shear: ShearCaptcha,Gif: GifCaptcha,DiyChar: DiyCharCaptcha,DiyCompute: DiyComputeCaptcha,};const getCaptcha = async (captchaType) => {try {let res;switch (captchaType) {case "Line":res = await getLineCaptcha();break;case "Circle":res = await getCircleCaptcha();break;case "Shear":res = await getShearCaptcha();break;case "Gif":res = await getGifCaptcha();break;case "DiyChar":res = await getDiyCharCaptcha();break;case "DiyCompute":res = await getDiyComputeCaptcha();break;default:throw new Error("Invalid captcha type");}captchaRefs[captchaType].value = res.data;} catch (error) {console.error(`獲取 ${captchaType} 驗證碼時出錯:`, error);ElMessage.error(`獲取 ${captchaType} 驗證碼時出錯,請稍后再試`);}
};const changeCaptchaImg = async (captchaType) => {await getCaptcha(captchaType);
};const revokeCaptchaUrls = () => {for (const captchaType in captchaRefs) {if (captchaRefs[captchaType].value) {URL.revokeObjectURL(captchaRefs[captchaType].value);}}
};onMounted(async () => {await Promise.all([getCaptcha("Line"),getCaptcha("Circle"),getCaptcha("Shear"),getCaptcha("Gif"),getCaptcha("DiyChar"),getCaptcha("DiyCompute"),]);
});onBeforeUnmount(() => {revokeCaptchaUrls();
});
</script><style lang="scss" scoped></style>