女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

SpringBoot分布式驗證碼登錄方案

jf_ro2CN3Fa ? 來源:碼畜君 ? 2023-10-12 17:34 ? 次閱讀

前言

為了防止世界被破壞,為了守護世界的和平。。。說錯了,重來~

為了防止驗證系統被暴力破解,很多系統都增加了驗證碼效驗,比較常見的就是圖片二維碼,業內比較安全的是短信驗證碼,當然還有一些拼圖驗證碼,加入人工智能的二維碼等等,我們今天的主題就是前后端分離的圖片二維碼登錄方案。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

前后端未分離的驗證碼登錄方案

傳統的項目大都是基于session交互的,前后端都在一個項目里面,比如傳統的SSH項目或者一些JSP系統,當前端頁面觸發到獲取驗證碼請求,可以將驗證碼里面的信息存在上下文中,所以登錄的時候只需要 用戶名密碼驗證碼即可。

驗證碼生成流程如下

7bb22bda-68d7-11ee-939d-92fbcf53809c.jpg

登錄驗證流程如下

7bc315d0-68d7-11ee-939d-92fbcf53809c.jpg

可以發現,整個登錄流程還是依賴session上下文的,并且由后端調整頁面。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

前后端分離的驗證碼登錄方案

隨著系統和業務的不停升級,前后端代碼放在一起的項目越來越臃腫,已經無法快速迭代和職責區分了,于是紛紛投入了前后端分離的懷抱,發現代碼和職責分離以后,開發效率越來越高了,功能迭代還越來越快,但是以前的驗證碼登錄方案就要更改了。

驗證碼生成流程如下

7bcd88a8-68d7-11ee-939d-92fbcf53809c.jpg

對比原來的方案,增加了redis中間件,不再是存在session里面了,但是后面怎么區分這個驗證碼是這個請求生成的呢?所以我們加入了唯一標識符來區分

登錄驗證流程如下

7bda2694-68d7-11ee-939d-92fbcf53809c.jpg

可以發現,基于前后端分離的分布式項目登錄方案對比原來,加了一個redis中間件和token返回,不再依賴上下文session,并且頁面調整也是由后端換到了前端

動手擼輪子

基于驗證碼的輪子還是挺多的,本文就以Kaptcha這個項目為例,通過springboot項目集成Kaptcha來實現驗證碼生成和登錄方案。

Kaptcha介紹

Kaptcha是一個基于SimpleCaptcha的驗證碼開源項目

我找的這個輪子是基于SimpleCaptcha二次封裝的,maven依賴如下


<dependency>
<groupId>com.github.pengglegroupId>
<artifactId>kaptchaartifactId>
<version>2.3.2version>
dependency>

新建項目并加入依賴

依賴主要有 SpringBoot、Kaptcha、Redis

pom.xml

<projectxmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>

<groupId>com.lzpgroupId>
<artifactId>kaptchaartifactId>
<version>1.0-SNAPSHOTversion>

<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.0.RELEASEversion>
<relativePath/>
parent>

<dependencies>

<dependency>
<groupId>com.github.pengglegroupId>
<artifactId>kaptchaartifactId>
<version>2.3.2version>
dependency>

<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>


<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>


<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
dependency>

<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.3version>
dependency>

<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
dependency>

dependencies>


<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>

project>

Redis配置類RedisConfig

@Configuration
publicclassRedisConfig{

@Bean
publicRedisTemplateredisTemplate(LettuceConnectionFactoryredisConnectionFactory){
RedisTemplateredisTemplate=newRedisTemplate();
redisTemplate.setKeySerializer(newStringRedisSerializer());
redisTemplate.setValueSerializer(newGenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(newStringRedisSerializer());
redisTemplate.setHashValueSerializer(newGenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
returnredisTemplate;
}

}

驗證碼配置類KaptchaConfig

@Configuration
publicclassKaptchaConfig{
@Bean
publicDefaultKaptchaproducer(){

DefaultKaptchadefaultKaptcha=newDefaultKaptcha();
Propertiesproperties=newProperties();
properties.setProperty("kaptcha.border","no");
properties.setProperty("kaptcha.border.color","105,179,90");
properties.setProperty("kaptcha.textproducer.font.color","black");
properties.setProperty("kaptcha.image.width","110");
properties.setProperty("kaptcha.image.height","40");
properties.setProperty("kaptcha.textproducer.char.string","23456789abcdefghkmnpqrstuvwxyzABCDEFGHKMNPRSTUVWXYZ");
properties.setProperty("kaptcha.textproducer.font.size","30");
properties.setProperty("kaptcha.textproducer.char.space","3");
properties.setProperty("kaptcha.session.key","code");
properties.setProperty("kaptcha.textproducer.char.length","4");
properties.setProperty("kaptcha.textproducer.font.names","宋體,楷體,微軟雅黑");
//properties.setProperty("kaptcha.obscurificator.impl","com.xxx");可以重寫實現類
properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise");
Configconfig=newConfig(properties);
defaultKaptcha.setConfig(config);

returndefaultKaptcha;
}

驗證碼控制層CaptchaController

為了方便代碼寫一塊了,講究看

packagecom.lzp.kaptcha.controller;

importcom.google.code.kaptcha.impl.DefaultKaptcha;
importcom.lzp.kaptcha.service.CaptchaService;
importcom.lzp.kaptcha.vo.CaptchaVO;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.ResponseBody;
importorg.springframework.web.bind.annotation.RestController;
importsun.misc.BASE64Encoder;

importjavax.imageio.ImageIO;
importjava.awt.image.BufferedImage;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;

@RestController
@RequestMapping("/captcha")
publicclassCaptchaController{

@Autowired
privateDefaultKaptchaproducer;

@Autowired
privateCaptchaServicecaptchaService;

@ResponseBody
@GetMapping("/get")
publicCaptchaVOgetCaptcha()throwsIOException{

//生成文字驗證碼
Stringcontent=producer.createText();
//生成圖片驗證碼
ByteArrayOutputStreamoutputStream=null;
BufferedImageimage=producer.createImage(content);

outputStream=newByteArrayOutputStream();
ImageIO.write(image,"jpg",outputStream);
//對字節數組Base64編碼
BASE64Encoderencoder=newBASE64Encoder();

Stringstr="data:image/jpeg;base64,";
Stringbase64Img=str+encoder.encode(outputStream.toByteArray()).replace("
","").replace("
","");

CaptchaVOcaptchaVO=captchaService.cacheCaptcha(content);
captchaVO.setBase64Img(base64Img);

returncaptchaVO;
}

}

驗證碼返回對象CaptchaVO

packagecom.lzp.kaptcha.vo;

publicclassCaptchaVO{
/**
*驗證碼標識符
*/
privateStringcaptchaKey;
/**
*驗證碼過期時間
*/
privateLongexpire;
/**
*base64字符串
*/
privateStringbase64Img;

publicStringgetCaptchaKey(){
returncaptchaKey;
}

publicvoidsetCaptchaKey(StringcaptchaKey){
this.captchaKey=captchaKey;
}

publicLonggetExpire(){
returnexpire;
}

publicvoidsetExpire(Longexpire){
this.expire=expire;
}

publicStringgetBase64Img(){
returnbase64Img;
}

publicvoidsetBase64Img(Stringbase64Img){
this.base64Img=base64Img;
}
}

Redis封裝類 RedisUtils

網上隨意找的,類里面注明來源,將就用,代碼較多就不貼了,文末有代碼獲取

驗證碼方法層CaptchaService

packagecom.lzp.kaptcha.service;

importcom.lzp.kaptcha.utils.RedisUtils;
importcom.lzp.kaptcha.vo.CaptchaVO;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.beans.factory.annotation.Value;
importorg.springframework.stereotype.Service;

importjava.util.UUID;

@Service
publicclassCaptchaService{

@Value("${server.session.timeout:300}")
privateLongtimeout;

@Autowired
privateRedisUtilsredisUtils;


privatefinalStringCAPTCHA_KEY="captcha";

publicCaptchaVOcacheCaptcha(Stringcaptcha){
//生成一個隨機標識符
StringcaptchaKey=UUID.randomUUID().toString();

//緩存驗證碼并設置過期時間
redisUtils.set(CAPTCHA_KEY.concat(captchaKey),captcha,timeout);

CaptchaVOcaptchaVO=newCaptchaVO();
captchaVO.setCaptchaKey(captchaKey);
captchaVO.setExpire(timeout);

returncaptchaVO;
}

}

用戶登錄對象封裝LoginDTO

packagecom.lzp.kaptcha.dto;

publicclassLoginDTO{

privateStringuserName;

privateStringpwd;

privateStringcaptchaKey;

privateStringcaptcha;

publicStringgetUserName(){
returnuserName;
}

publicvoidsetUserName(StringuserName){
this.userName=userName;
}

publicStringgetPwd(){
returnpwd;
}

publicvoidsetPwd(Stringpwd){
this.pwd=pwd;
}

publicStringgetCaptchaKey(){
returncaptchaKey;
}

publicvoidsetCaptchaKey(StringcaptchaKey){
this.captchaKey=captchaKey;
}

publicStringgetCaptcha(){
returncaptcha;
}

publicvoidsetCaptcha(Stringcaptcha){
this.captcha=captcha;
}
}

登錄控制層UserController

這塊我寫邏輯代碼了,相信大家都看的懂

packagecom.lzp.kaptcha.controller;

importcom.lzp.kaptcha.dto.LoginDTO;
importcom.lzp.kaptcha.utils.RedisUtils;
importcom.lzp.kaptcha.vo.UserVO;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.bind.annotation.PostMapping;
importorg.springframework.web.bind.annotation.RequestBody;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
publicclassUserController{

@Autowired
privateRedisUtilsredisUtils;

@PostMapping("/login")
publicUserVOlogin(@RequestBodyLoginDTOloginDTO){
Objectcaptch=redisUtils.get(loginDTO.getCaptchaKey());
if(captch==null){
//throw驗證碼已過期
}
if(!loginDTO.getCaptcha().equals(captch)){
//throw驗證碼錯誤
}
//查詢用戶信息

//判斷用戶是否存在不存在拋出用戶名密碼錯誤

//判斷密碼是否正確,不正確拋出用戶名密碼錯誤

//構造返回到前端的用戶對象并封裝信息和生成token

returnnewUserVO();
}
}

驗證碼獲取和查看

7be97284-68d7-11ee-939d-92fbcf53809c.jpg7bf6213c-68d7-11ee-939d-92fbcf53809c.jpg


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4887

    瀏覽量

    70257
  • Redis
    +關注

    關注

    0

    文章

    385

    瀏覽量

    11324
  • SpringBoot
    +關注

    關注

    0

    文章

    175

    瀏覽量

    318

原文標題:SpringBoot 分布式驗證碼登錄方案

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    用基于gin框架的Go語言來實現手機號發送短信驗證碼登錄

    現在大多數app或wap都實現了通過手機號獲取驗證碼進行驗證登錄,下面來看下用go來實現手機號發送短信驗證碼登錄的過程,基于的框架是gin
    的頭像 發表于 07-20 09:36 ?4894次閱讀
    用基于gin框架的Go語言來實現手機號發送短信<b class='flag-5'>驗證碼</b><b class='flag-5'>登錄</b>

    織夢dedecms登陸提示“驗證碼不正確”的完整解決方案

    != $svali)替換為:if( false)然后,在模板dede/templets/login.htm里去掉以下驗證碼的具體HTML代碼:驗證碼: 以上辦法可以解決dedecms登錄時提示
    發表于 03-10 23:53

    12306圖片驗證碼難倒了誰?

    ,現在不光要靠網速……(還有看人品)下面是摘自網上的新聞:  一次性輸入正確率僅為8%  為了防止搶票軟件破解,鐵道部12306網站不斷將登錄的圖形驗證碼更新,層出不窮的圖形碼讓一些網購車票的旅客
    發表于 12-08 10:29

    無法驗證郵箱,總是提示驗證碼錯誤,驗證碼明明是正確的。

    `無法驗證郵箱,總是提示驗證碼錯誤,驗證碼明明是正確的。是不是系統的bug?`
    發表于 05-12 10:41

    平臺是如何高效的破解市面上各家驗證碼平臺的各種形式驗證碼的?

    眾所周知,驗證碼的出現是為了區分人和機器,但隨著科技的發展,黑產從業者的可圖之利增多,驗證碼的戰場也進入了一段破解與抗破解的持久博弈。驗證碼在逐漸復雜的同時,黑灰產的攻擊手段也不斷提升。本文就從
    發表于 11-01 15:21

    基于加密短信驗證碼的移動安全支付解決方案

    針對移動支付過程中支付驗證碼容易泄露的問題,提出了基于加密短信息驗證碼的雙因素移動支付系統方案。該方案基于公開密鑰系統,使用公鑰基礎設施/認證機構( PKI/CA)的認證方法進行服務器
    發表于 11-29 14:40 ?0次下載
    基于加密短信<b class='flag-5'>驗證碼</b>的移動安全支付解決<b class='flag-5'>方案</b>

    SQLyog_12.4.1_帶驗證碼

    SQLyog_12.4.1_帶驗證碼.rar
    發表于 04-12 21:03 ?22次下載

    驗證碼能保證真的安全嗎?

    驗證碼的世界,竟然……如此觸目驚心! 這年頭,無論支付、注冊、還是登錄各種端口,哪怕是保障用戶安全的諸多舉措
    的頭像 發表于 06-10 09:31 ?1.2w次閱讀

    以一個真實網站的驗證碼為例,實現了基于一下KNN的驗證碼識別

    很多網站登錄都需要輸入驗證碼,如果要實現自動登錄就不可避免的要識別驗證碼。本文以一個真實網站的驗證碼為例,實現了基于一下KNN的
    的頭像 發表于 12-24 17:27 ?8009次閱讀

    驗證碼層出不窮?試試這個自動跳過驗證碼的工具

    目前網絡上越來越多使用驗證碼了,驗證碼的本意是阻止機器刷流量擠占服務器資源,這本來無可厚非;但是驗證碼已經變得越來越過分,別說機器人了,連人也經常沒法辨認!這就相當煩了,特別是被廣泛使用更多
    的頭像 發表于 11-15 10:42 ?6282次閱讀

    驗證碼太麻煩,自動跳過驗證碼神器試一試

    目前網絡上越來越多使用驗證碼了,驗證碼的本意是阻止機器刷流量擠占服務器資源,這本來無可厚非;但是驗證碼已經變得越來越過分,別說機器人了,連人也經常沒法辨認! 這就相當煩了,特別是被廣泛使用更多
    的頭像 發表于 11-15 11:15 ?1w次閱讀

    爬蟲實現目標網站驗證碼登陸

    在爬蟲訪問目標網站的過程中,很多網站為了避免被惡意訪問,需要設置驗證碼登錄,這樣是為了避免非人類的訪問。今天我們學習下如何使用Python爬蟲實現驗證碼登錄并且將生成的
    發表于 12-11 15:27 ?2563次閱讀

    帶帶弟弟OCR通用驗證碼識別SDK免費開源版

    在使用爬蟲登錄網站的時候,經常輸入用戶名和密碼后會遇到驗證碼,簡單一點的有字母驗證碼,復雜一點的有滑塊驗證碼,點選文章和點選圖片驗證碼。這些
    的頭像 發表于 03-30 17:26 ?5000次閱讀

    驗證碼到底在驗證啥?聊一聊驗證碼是怎么為難我們人類的

    在文章開頭,老狐先給大家玩一個驗證碼的游戲,猜出圖中驗證碼字母。
    的頭像 發表于 08-12 10:25 ?2573次閱讀
    <b class='flag-5'>驗證碼</b>到底在<b class='flag-5'>驗證</b>啥?聊一聊<b class='flag-5'>驗證碼</b>是怎么為難我們人類的

    Java 中驗證碼的使用

    今天我們講一下在 Java 中驗證碼的使用。 驗證碼生成 本效果是利用easy-captcha工具包實現,首先需要添加相關依賴到pom.xml中,代碼如下: com .github.whvcse
    的頭像 發表于 09-25 11:11 ?1426次閱讀
    Java 中<b class='flag-5'>驗證碼</b>的使用