使用SpringBoot?+?Vue?+?Redis實現(xiàn)驗證碼登錄功能全過程
前言
驗證碼在項目中使用到的較多,主要的目的是防止bl破解和自動化腳本攻擊。驗證碼需要人工識別圖片中的內容,可以組織批量的自動化攻擊。同時可以減輕數(shù)據(jù)庫的訪問壓力,驗證碼不通過的情況下,不去進行查表操作。這篇文章大致說明一下具體的實現(xiàn)過程~
實現(xiàn)效果演示
這里的圖片二維碼是后端接口返回的base64(圖片轉base64),然后渲染到頁面部分。用戶點擊這個圖片可以生成新的驗證碼。驗證碼的有效時長是1分鐘、超過有效期 ,驗證失效。(有效時長可以通過改變驗證碼存入Redis的時長來調整)。

實現(xiàn)過程大致說明
1、后端pom文件引入Redis依賴,redis 連接 等下相關配置;
2、生成驗證碼保存到Redis中(同時設置過期時間);
3、將生成的圖片驗證碼以base64格式返回給前端,渲染出來;
4、用戶輸入的驗證碼和Redis的比對;
后端接口實現(xiàn)(核心部分)
驗證碼生成部分
/**
* 后臺生成圖形驗證碼 :有效
* @param response
* @param key
*/
@GetMapping(value = "/randomImage/{key}")
public Result randomImage(HttpServletResponse response, @PathVariable("key") String key){
logger.info("進入后臺生成圖形驗證碼方法 ...");
JSONObject jsonObject = new JSONObject();
try {
//生成驗證碼
String code = RandomUtil.randomString(BASE_CHECK_CODES,4);
//存到redis中
String lowerCaseCode = code.toLowerCase();
// 加入密鑰作為混淆,避免簡單的拼接,被外部利用,用戶自定義該密鑰即可
logger.info("RedisKey: {}", key);
String keyPrefix = Md5Util.md5Encode(key + SIGNATURE_SECRET, "utf-8");
String realKey = keyPrefix + lowerCaseCode;
redisUtil.removeAll(keyPrefix);
redisUtil.set(realKey, lowerCaseCode, 60);
logger.info("獲取驗證碼,Redis key = {},checkCode = {}", realKey, code);
//返回前端
String base64 = RandImageUtil.generate(code);
jsonObject.put("base64", base64);
return Result.ok().data(jsonObject);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return Result.error().code(ResultCode.GET_VERIFY_CODE_ERROR.getCode())
.message(ResultCode.GET_VERIFY_CODE_ERROR.getMessage());
}
}生成base64圖片字符串
/**
* 生成base64字符串
* @param resultCode
* @return
* @throws IOException
*/
public static String generate(String resultCode) throws IOException {
BufferedImage image = getImageBuffer(resultCode);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
//寫入流中
ImageIO.write(image, IMG_FORMAT, byteStream);
//轉換成字節(jié)
byte[] bytes = byteStream.toByteArray();
//轉換成base64串
String base64 = Base64.getEncoder().encodeToString(bytes).trim();
//刪除 \r\n
base64 = base64.replaceAll("\n", "").replaceAll("\r", "");
//寫到指定位置
//ImageIO.write(bufferedImage, "png", new File(""));
return BASE64_PRE+base64;
}驗證部分,將用戶輸入的驗證碼和Redis存儲的比對。
@RequestMapping(value = "/Login/userLogin", method = RequestMethod.POST)
public Result loginSystem(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request) {
log.info("用戶登錄開始:{}", sysLoginModel);
String captcha = sysLoginModel.getCaptcha();
String checkKey = sysLoginModel.getCheckKey();
if(captcha==null){
return Result.error().code(ResultCode.VERIFY_CODE_ERROR.getCode())
.message(ResultCode.VERIFY_CODE_ERROR.getMessage());
}
String lowerCaseCaptcha = captcha.toLowerCase();
String realKey = Md5Util.md5Encode(checkKey + SIGNATURE_SECRET, "utf-8") + lowerCaseCaptcha;
Object checkCode = redisUtil.get(realKey);
log.info("Redis存儲驗證碼: {} , 用戶輸入驗證碼: {}", checkCode , lowerCaseCaptcha);
if(checkCode == null || !checkCode.equals(lowerCaseCaptcha)) {
return Result.error().code(ResultCode.VERIFY_CODE_NOT_EXIST.getCode()).message(ResultCode.VERIFY_CODE_NOT_EXIST.getMessage());
}
}前端接口實現(xiàn) (核心部分)
頁面實現(xiàn)部分、用的vue2
<el-form-item prop="captcha"> <div class="captcha-box"> <el-input v-model="form.captcha" placeholder="驗證碼" prefix-icon="el-icon-key" /> <div class="captcha-img"> <img v-if="randCodeData.requestCodeSuccess" style="margin-top: 2px; max-width: initial" :src="randCodeData.randCodeImage" @click="handleChangeCheckCode" /> </div> </div> </el-form-item>
js部分實現(xiàn)
handleChangeCheckCode() {
const _this = this;
this.randCodeData.checkKey =
new Date().getTime() + Math.random().toString(36).slice(-4);
this.$axios
.getRandomImage(_this.randCodeData.checkKey)
.then(function (resp) {
if (resp.code == 200) {
_this.randCodeData.randCodeImage = resp.data.base64;
_this.randCodeData.requestCodeSuccess = true;
} else {
_this.$message.error(resp.message);
}
});
},

總結
到此這篇關于使用SpringBoot + Vue + Redis實現(xiàn)驗證碼登錄功能的文章就介紹到這了,更多相關SpringBoot+Vue+Redis實現(xiàn)驗證碼登錄內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Springboot+mybatis-plus+注解實現(xiàn)數(shù)據(jù)權限隔離
本文將結合實例代碼,介紹Springboot+mybatis-plus+注解實現(xiàn)數(shù)據(jù)權限隔離,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧2021-07-07
SpringBoot接口中如何直接返回圖片數(shù)據(jù)
這篇文章主要介紹了SpringBoot接口中如何直接返回圖片數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
高并發(fā)環(huán)境下安全修改同一行數(shù)據(jù)庫數(shù)據(jù)的策略分享
隨著互聯(lián)網(wǎng)技術的發(fā)展,越來越多的應用需要在高并發(fā)環(huán)境中運行,數(shù)據(jù)庫的并發(fā)控制成為了業(yè)務的關鍵,本文將介紹如何在高并發(fā)情況下,安全地修改數(shù)據(jù)庫中的同一行數(shù)據(jù),需要的可以參考一下2023-06-06
SpringBoot攔截器如何獲取http請求參數(shù)
這篇文章主要給大家介紹了SpringBoot攔截器如何獲取http請求參數(shù)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09

