做个人的网站怎么做,装修软件排行榜前十名,免费做效果图的网站有哪些,媒体查询响应式布局一、背景 
1.1 概述 
传统字符型验证码展示-填写字符-比对答案的流程#xff0c;目前已可被机器暴力破解#xff0c;应用程序容易被自动化脚本和机器人攻击。  摒弃传统字符型验证码#xff0c;采用行为验证码采用嵌入式集成方式#xff0c;接入方便#xff0c;安全#…一、背景 
1.1 概述 
传统字符型验证码展示-填写字符-比对答案的流程目前已可被机器暴力破解应用程序容易被自动化脚本和机器人攻击。  摒弃传统字符型验证码采用行为验证码采用嵌入式集成方式接入方便安全高效。验证码展示-采集用户行为-分析用户行为流程用户只需要产生指定的行为轨迹不需要键盘手动输入极大优化了传统验证码用户体验不佳的问题同时快速、准确的返回人机判定结果。  
1.2 应用场景 
网站登录保护用户账号免受非法登录尝试在线表单提交避免垃圾邮件和恶意数据填充论坛或社区防止机器人自动发帖和灌水支付验证保障交易安全防止欺诈行为 
二、anji-plus 
AJ-Captcha行为验证码包含滑动拼图、文字点选两种方式UI支持弹出和嵌入两种方式。后端提供Java实现前端提供了php、angular、html、vue、uni-app、flutter、android、ios等代码示例。 
代码开源地址https://gitee.com/anji-plus/captcha 文档地址https://ajcaptcha.beliefteam.cn/captcha-doc/ 
2.1 功能简介 
功能描述验证码类型滑动拼图 blockPuzzle / 文字点选 clickWord验证用户拖动/点击一次验证码拼图即视为一次“验证”不论拼图/点击是否正确二次校验验证数据随表单提交到后台后后台需要调用captchaService.verification做二次校验。目的是核实验证数据的有效性。 
2.2 交互流程 
① 用户访问应用页面请求显示行为验证码 ② 用户按照提示要求完成验证码拼图/点击 ③ 用户提交表单前端将第二步的输出一同提交到后台 ④ 验证数据随表单提交到后台后后台需要调用captchaService.verification做二次校验。 ⑤ 第4步返回校验通过/失败到产品应用后端再返回到前端。如下图所示。  
三、代码实现 
3.1 引入依赖 
dependencygroupIdcom.anji-plus/groupIdartifactIdspring-boot-starter-captcha/artifactIdversion1.3.0/version
/dependency3.2 配置 
# 验证码配置
aj:captcha:########## 重点关注 ########### 验证码类型default,blockPuzzle,clickWordtype: default# 底图路径支持全路径、项目资源路径jigsaw: classpath:images/jigsaw# 滑动图路径支持全路径、项目资源路径pic-click: classpath:images/pic-click# 缓存类型local,redis,othercache-type: redis# local缓存的阈值,达到这个值清除缓存cache-number: 1000# local定时清除过期缓存(单位秒)设置为0代表不执行timing-clear: 180# 滑块验证码的偏移量slip-offset: 5# 滑块验证码的加密坐标aes-status: true# 滑块验证码的滑块干扰项interference-options: 2# 文字验证码的文字数量【暂不可用】click-word-count: 4# 文字验证码的文字字体font-type: WenQuanZhengHei.ttf# 文字验证码的字体样式font-style: 1# 文字验证码的字体大小font-size: 25# 水印文字water-mark: 强哥软件# 水印文字字体water-font: WenQuanZhengHei.ttf########## 接口相关配置 ########### 历史数据清理是否开启history-data-clear-enable: false# 接口请求次数一分钟限制是否开启req-frequency-limit-enable: true# 验证失败5次get接口锁定req-get-lock-limit: 5# 验证失败后锁定时间间隔,sreq-get-lock-seconds: 360# get接口一分钟内请求数限制req-get-minute-limit: 30# check接口一分钟内请求数限制req-check-minute-limit: 60# verify接口一分钟内请求数限制req-verify-minute-limit: 603.3 自定义验证码存储 
使用redis存储验证码 
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency实现CaptchaCacheService 接口 
package com.qiangesoft.captcha.cache;import com.anji.captcha.service.CaptchaCacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;import java.util.concurrent.TimeUnit;/*** redis缓存验证码** author qiangesoft* date 2024-05-10*/
public class CaptchaCacheServiceRedisImpl implements CaptchaCacheService {Autowiredprivate StringRedisTemplate stringRedisTemplate;Overridepublic void set(String key, String value, long expiresInSeconds) {stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);}Overridepublic boolean exists(String key) {return stringRedisTemplate.hasKey(key);}Overridepublic void delete(String key) {stringRedisTemplate.delete(key);}Overridepublic String get(String key) {return stringRedisTemplate.opsForValue().get(key);}Overridepublic Long increment(String key, long val) {return stringRedisTemplate.opsForValue().increment(key, val);}Overridepublic String type() {return redis;}
} 
配置 在resources目录新建META-INF.services文件夹新建文件名为com.anji.captcha.service.CaptchaCacheService内容为com.qiangesoft.captcha.cache.CaptchaCacheServiceRedisImpl 
3.4 登录验证接口 
package com.qiangesoft.captcha.controller;import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.qiangesoft.captcha.pojo.LoginDTO;
import com.qiangesoft.captcha.pojo.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;/*** 登录接口** author qiangesoft* date 2024-05-10*/
Controller
public class LoginController {Autowiredprivate CaptchaService captchaService;GetMapping(/)public String index() {return login;}ResponseBodyPostMapping(/login)public ResultVO login(RequestBody LoginDTO loginDTO) {// 登录二次校验CaptchaVO captchaVO  new CaptchaVO();captchaVO.setCaptchaVerification(loginDTO.getCaptcha());ResponseModel response  captchaService.verification(captchaVO);if (!response.isSuccess()) {throw new RuntimeException(图片验证码校验失败);}// todo 认证逻辑return ResultVO.ok();}} 
3.5 vue方式 
主要代码如下 
templatediv classlogin-bgel-form stylewidth: 500px;height: 40px;margin: autoel-form-item label账号 propusernameel-input v-modelusername placeholder账号/el-input/el-form-itemel-form-item label密码 proppasswordel-input v-modelpassword placeholder密码/el-input/el-form-itemel-form-itemel-button typeprimary clickcheckParam登录/el-button/el-form-item/el-formVerifyrefverifycaptcha-typeblockPuzzle:img-size{width:400px,height:200px}successlogin/!--    Verify--!--      refverify--!--      captcha-typeclickWord--!--      :img-size{width:400px,height:200px}--!--      successlogin--!--    /--/div
/templatescript
import Verify from ./../components/verifition/Verify
import { Message } from element-ui
import { login } from /apiexport default {components: {Verify},data () {return {username: admin,password: 123456}},beforeDestroy () {document.removeEventListener(keyup, this.handlerKeyup)},created () {document.addEventListener(keyup, this.handlerKeyup)},methods: {handlerKeyup (e) {const keycode  document.all ? event.keyCode : e.whichif (keycode  13) {this.checkParam()}},checkParam () {if (!this.username || !this.password) {Message.error(请先输入账号密码)}this.$refs.verify.show()},login (params) {login({username: this.username,password: this.password,captcha: params.captchaVerification}).then(res  {const code  res.codeif (code  200) {Message.success(登录成功)this.$router.push(/index)} else {Message.error(res.message)}})}}
}
/script 
3.6 html方式 
引入依赖 
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId
/dependency配置静态资源 
package com.qiangesoft.captcha.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 全局异常处理** author qiangesoft* date 2024-03-19*/
Configuration
public class WebConfig implements WebMvcConfigurer {Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler(/static/**).addResourceLocations(classpath:/static/);}
}html代码 
!DOCTYPE html
html langen xmlns:thhttp://www.thymeleaf.org
headmeta http-equivContent-Type contenttext/html; charsetutf-8meta nameviewportcontentwidthdevice-width,initial-scale1,minimum-scale1,maximum-scale1,user-scalableno/titleverify插件demo/titlelink relstylesheet typetext/css th:href{/static/css/verify.css}scriptif (!window.Promise) {document.writeln(script srchttps://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js  /  script);}/scriptstyle.btn {border: none;outline: none;width: 110px;height: 40px;line-height: 40px;text-align: center;cursor: pointer;background-color: #409EFF;color: #fff;font-size: 16px;}/style
/headbody
div classboxh3用户登录/h3账号input typetext idusername placeholder账号 valueadmin/ br/br/密码input typepassword idpassword placeholder密码 value123456/br/br/button classbtn idbtn滑块登录/buttonbutton classbtn idbtn1文字登录/buttondiv idmpanel stylemargin-top:50px;/divdiv idmpanel1 stylemargin-top:50px;/div
/divscript typetext/javascript srchttps://cdn.bootcdn.net/ajax/libs/jquery/1.9.1/jquery.js/script
script th:src{/static/js/crypto-js.js}/script
script th:src{/static/js/ase.js}/script
script th:src{/static/js/verify.js}/scriptscript// 滑块$(#mpanel).slideVerify({baseUrl: http://localhost:8028,mode: pop,containerId: btn,imgSize: {width: 400px,height: 200px,},barSize: {width: 400px,height: 40px,},// 检验参数合法性的函数mode pop有效beforeCheck: function () {// todo 可进行参数校验return true},// 加载完毕的回调ready: function () {},// 成功的回调success: function (params) {const username  $(#username).val();const password  $(#password).val();$.ajax({url: /login,type: post,contentType: application/json,dataType: json,data: JSON.stringify({username: username,password: password,captcha: params.captchaVerification}),success: function (res) {if (res.code  200) {alert(登录成功);} else {alert(res.message);}},error: function (e) {alert(请求失败)}})},// 失败的回调error: function () {}});// 文字点击$(#mpanel1).pointsVerify({baseUrl: http://localhost:8028,containerId: btn1,mode: pop,imgSize: {width: 400px,height: 200px,},beforeCheck: function () {return true},ready: function () {},success: function (params) {const username  $(#username).val();const password  $(#password).val();$.ajax({url: /login,type: post,contentType: application/json,dataType: json,data: JSON.stringify({username: username,password: password,captcha: params.captchaVerification}),success: function (res) {if (res.code  200) {alert(登录成功);} else {alert(res.message);}},error: function (e) {alert(请求失败)}})},error: function () {}});
/script
/body/html四、测试 
4.1 接口调用 
依赖中默认接口 
功能描述请求方式获取验证码/captcha/getpost核对验证码/captcha/checkpost 
接口调用流程  
获取验证码接口/captcha/get 请求参数 
{captchaType: blockPuzzle,  // 验证码类型 clickWordclientUid: 唯一标识  // 客户端UI组件id,组件初始化时设置一次UUID非必传参数
}响应数据 
{repCode: 0000,repData: {originalImageBase64: 底图base64,point: {    // 默认不返回的校验的就是该坐标信息允许误差范围x: 205,y: 5},jigsawImageBase64: 滑块图base64,token: 71dd26999e314f9abb0c635336976635, // 一次校验唯一标识secretKey: 16位随机字符串, // aes秘钥开关控制前端根据此值决定是否加密result: false,opAdmin: false},success: true,error: false
}核对验证码接口/captcha/check 请求参数 
{captchaType: blockPuzzle,pointJson: QxIVdlJoWUi04iM65hTow,  // aes加密坐标信息token: 71dd26999e314f9abb0c635336976635  // get请求返回的token
}响应数据 
{repCode: 0000,repData: {captchaType: blockPuzzle,token: 71dd26999e314f9abb0c635336976635,result: true,opAdmin: false},success: true,error: false
}4.2 vue 4.3 html 五、源码地址 
码云https://gitee.com/qiangesoft/boot-business/tree/master/boot-business-captcha 
方便的话博客点个小心心码云仓库点个star呗