SpringBoot使用easy-captcha 實(shí)現(xiàn)驗(yàn)證碼登錄功能(解決思路)
一、 環(huán)境準(zhǔn)備
1. 解決思路
- 后端使用 easy-captcha 創(chuàng)建驗(yàn)證碼對(duì)象。
- 將驗(yàn)證碼文本存儲(chǔ)到 Redis 中,并生成一個(gè)隨機(jī)的 key。
- 將驗(yàn)證碼的 Base64 字符串和 key 返回給前端。
- 前端通過(guò) Base64 字符串顯示驗(yàn)證碼圖片,并將 key 保存起來(lái)。
- 登錄時(shí),前端將用戶輸入的驗(yàn)證碼和 key 發(fā)送到后端。
- 后端通過(guò) key 從 Redis 中獲取驗(yàn)證碼文本,并進(jìn)行比對(duì)驗(yàn)證。
2. 接口文檔
URL
GET /captcha
參數(shù)
無(wú)
返回
{ "msg": "操作成功", "code": 200, "data": { "uuid": "b71fafb1a91b4961afb27372bd3af77c", "captcha": "data:image/png;base64,iVBORw0KGgoAAAA", "code": "nrew" } }
3. redis下載
見(jiàn) redis安裝配置教程
二、后端實(shí)現(xiàn)
1. 引入依賴
在 pom.xml 文件中引入 easy-captcha
和 Redis
相關(guān)依賴:
<dependency> <groupId>com.github.whvcse</groupId> <artifactId>easy-captcha</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2. 添加配置
在application.yml
里添加連接redis
數(shù)據(jù)庫(kù)的配置信息:
spring: redis: open: true database: 1 host: localhost port: 6379
3. 后端代碼實(shí)現(xiàn)
controller:
@RestController public class LoginController { @Autowired private RedisTemplate redisTemplate; @GetMapping("/captcha") public Result captcha() { // 創(chuàng)建一個(gè) SpecCaptcha 對(duì)象,設(shè)置驗(yàn)證碼圖片的寬度、高度和字符長(zhǎng)度 SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4); // 生成驗(yàn)證碼文本,并將其轉(zhuǎn)換為小寫(xiě)(方便后續(xù)比較,忽略大小寫(xiě)) String code = specCaptcha.text().toLowerCase(); // 生成一個(gè)唯一的 UUID,用于存儲(chǔ)驗(yàn)證碼到 Redis 中 String uuid = IdUtil.simpleUUID(); // 將驗(yàn)證碼文本存入 Redis,并設(shè)置過(guò)期時(shí)間為 2 分鐘(120 秒) // 這樣可以確保驗(yàn)證碼在一定時(shí)間后自動(dòng)失效,避免被惡意利用 this.redisTemplate.opsForValue().set(uuid, code, 120, TimeUnit.SECONDS); // 創(chuàng)建一個(gè) Map,用于存儲(chǔ)返回給前端的數(shù)據(jù) Map<String, String> map = new HashMap<String, String>(3); // 將 UUID 存入 Map,前端需要將這個(gè) UUID 一起發(fā)送到后端進(jìn)行驗(yàn)證 map.put("uuid", uuid); // 將生成的驗(yàn)證碼文本存入 Map(可選,通常前端不需要知道驗(yàn)證碼文本) map.put("code", code); // 將驗(yàn)證碼圖片轉(zhuǎn)換為 Base64 字符串,并存入 Map // 前端可以通過(guò)這個(gè) Base64 字符串生成驗(yàn)證碼圖片 map.put("captcha", specCaptcha.toBase64()); // 返回 Result 對(duì)象,其中包含驗(yàn)證碼圖片的 Base64 字符串和 UUID // Result.ok() 表示操作成功,put("data", map) 將 Map 數(shù)據(jù)放入響應(yīng)中 return Result.ok().put("data", map); } @PostMapping("/login") public Result login(@RequestBody LoginForm loginForm, HttpSession session){ //驗(yàn)證碼校驗(yàn) String code = (String) this.redisTemplate.opsForValue().get(loginForm.getUuid()); //判斷驗(yàn)證碼是否有效 if(code == null){ return Result.error("驗(yàn)證碼已過(guò)期"); } //判斷驗(yàn)證碼是否正確 if(!code.equals(loginForm.getCaptcha())){ return Result.error("驗(yàn)證碼錯(cuò)誤"); } //判斷用戶名是否正確 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("username", loginForm.getUsername()); User user = this.userService.getOne(queryWrapper); if(user == null){ return Result.error("用戶名錯(cuò)誤"); } //判斷密碼是否正確 String password = SecureUtil.sha256(loginForm.getPassword()); if(!password.equals(user.getPassword())){ return Result.error("密碼錯(cuò)誤"); } //驗(yàn)證用戶是否可用 if(user.getStatus() == 0) { return Result.error("賬號(hào)已被鎖定,請(qǐng)聯(lián)系管理員"); } //登錄成功 session.setAttribute("user", user); //創(chuàng)建token String token = this.jwtUtil.createToken(String.valueOf(user.getUserId())); this.redisTemplate.opsForValue().set("communityuser-"+user.getUserId(), token,jwtUtil.getExpire()); Map<String,Object> map = new HashMap<>(); map.put("token", token); map.put("expire", jwtUtil.getExpire()); LogAspect.user = user; return Result.ok().put("data", map); } }
RedisTemplate
是 Spring Data Redis 提供的一個(gè)高級(jí)抽象,封裝了 Redis 的操作。它支持多種數(shù)據(jù)結(jié)構(gòu)(如字符串、列表、集合、哈希等),并提供了豐富的操作方法。通過(guò) RedisTemplate
,可以方便地執(zhí)行 Redis 命令,而無(wú)需直接使用 Redis 的原生客戶端。
常用方法:
- opsForValue():用于操作 Redis 中的字符串(
String
)數(shù)據(jù)。 - opsForList():用于操作 Redis 中的列表(
List
)數(shù)據(jù)。 - opsForSet():用于操作 Redis 中的集合(
Set
)數(shù)據(jù)。 - opsForHash():用于操作 Redis 中的哈希(
Hash
)數(shù)據(jù)。 - opsForZSet():用于操作 Redis 中的有序集合(
Sorted Set
)數(shù)據(jù)。
4. 前端代碼實(shí)現(xiàn)
獲取驗(yàn)證碼
前端通過(guò)調(diào)用后端接口獲取驗(yàn)證碼圖片和 UUID。這個(gè) UUID 用于在后端標(biāo)識(shí)驗(yàn)證碼的唯一性。
// 獲取驗(yàn)證碼 getCaptcha() { getCaptchaImg().then(res => { this.captchaPath = res.data.captcha; // 將驗(yàn)證碼圖片的 Base64 字符串賦值給 captchaPath this.loginForm.uuid = res.data.uuid; // 將 UUID 賦值給 loginForm 的 uuid 屬性 if (process.env.NODE_ENV === 'development') { this.loginForm.captcha = res.data.code; // 在開(kāi)發(fā)環(huán)境中自動(dòng)填充驗(yàn)證碼(方便測(cè)試) } }); }
顯示驗(yàn)證碼
前端通過(guò) el-image 組件顯示驗(yàn)證碼圖片,并提供點(diǎn)擊刷新功能。
<el-image class="captcha-img" :src="captchaPath" <!-- 綁定驗(yàn)證碼圖片的 Base64 字符串 --> @click="getCaptcha()" <!-- 點(diǎn)擊圖片時(shí)重新獲取驗(yàn)證碼 --> />
3. 提交表單時(shí)驗(yàn)證驗(yàn)證碼
用戶輸入驗(yàn)證碼后,點(diǎn)擊登錄按鈕提交表單。前端將用戶輸入的驗(yàn)證碼和 UUID 一起發(fā)送到后端進(jìn)行驗(yàn)證。
handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true; this.$store.dispatch('user/login', this.loginForm) .then(() => { this.$router.push({ path: this.redirect || '/' }); // 登錄成功后跳轉(zhuǎn) }) .catch(() => { this.getCaptcha(); // 登錄失敗,重新獲取驗(yàn)證碼 this.loading = false; }); } else { return false; } }); }
到此這篇關(guān)于SpringBoot使用 easy-captcha 實(shí)現(xiàn)驗(yàn)證碼登錄功能的文章就介紹到這了,更多相關(guān)SpringBoot驗(yàn)證碼登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java如何發(fā)起http請(qǐng)求的實(shí)現(xiàn)(GET/POST)
這篇文章主要介紹了Java如何發(fā)起http請(qǐng)求的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03java8列表中通過(guò)stream流根據(jù)對(duì)象屬性去重的三種方式
這篇文章主要介紹了java8列表中通過(guò)stream流根據(jù)對(duì)象屬性去重的三種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08JavaFx實(shí)現(xiàn)登錄成功跳轉(zhuǎn)到程序主頁(yè)面
這篇文章主要為大家詳細(xì)介紹了JavaFx實(shí)現(xiàn)登錄成功跳轉(zhuǎn)到程序主頁(yè)面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06SpringBoot3.2.2整合MyBatis Plus3.5.5的詳細(xì)過(guò)程
這篇文章給大家介紹了SpringBoot3.2.2整合MyBatis Plus3.5.5的詳細(xì)過(guò)程,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01