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

