滑动验证码和点选验证码
1.引入依赖
<!-- 验证码-->
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-captcha</artifactId>
<version>1.3.0</version>
</dependency>
2.编写controller
@Resource
private CaptchaService captchaService;
@PostMapping("/get") // 获取图片
public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) {
assert request.getRemoteHost()!=null;
data.setBrowserInfo(getRemoteId(request));
return captchaService.get(data);
}
@PostMapping("/check") // 进行校验
public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) {
data.setBrowserInfo(getRemoteId(request));
return captchaService.check(data);
}
@PostMapping("/verify") // 二次校验
public ResponseModel verify(@RequestBody CaptchaVO data, HttpServletRequest request) {
return captchaService.verification(data);
}
public static final String getRemoteId(HttpServletRequest request) {
String xfwd = request.getHeader("X-Forwarded-For");
String ip = getRemoteIpFromXfwd(xfwd);
String ua = request.getHeader("user-agent");
if (StringUtils.isNotBlank(ip)) {
return ip + ua;
}
return request.getRemoteAddr() + ua;
}
private static String getRemoteIpFromXfwd(String xfwd) {
if (StringUtils.isNotBlank(xfwd)) {
String[] ipList = xfwd.split(",");
return StringUtils.trim(ipList[0]);
}
return null;
}
3.编写CaptchaCacheServiceRedisImpl
@Slf4j
@Service
@RequiredArgsConstructor
public class CaptchaCacheServiceRedisImpl implements CaptchaCacheService {
@Override
public String type() {
return "redis";
}
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public void set(String key, String value, long expiresInSeconds) {
stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
}
@Override
public boolean exists(String key) {
return stringRedisTemplate.hasKey(key);
}
@Override
public void delete(String key) {
stringRedisTemplate.delete(key);
}
@Override
public String get(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
/*@Override
public Long increment(String key, long val) {
return stringRedisTemplate.opsForValue().increment(key,val);
}*/
}
需要配置redis,这里不多说
4.配置文件
# aj 验证码
aj:
captcha:
# 自定义滑块背景图,原图尺寸为310*155,格式必须为png,
resource/images/jigsaw/original目录下
jigsaw: classpath:images/jigsaw
# 存放点击验证码图片的目录,存放在lihua-captcha模块的resource/images/custom-pic-click目录下
pic-click: classpath:images/custom-pic-click
# 验证码缓存类型,支持 redis/local
cache-type: redis
# 实例化验证码类型
type: default
# 水印
water-mark: '@mytime'
# 误差值 5 像素
slip-offset: 5
# 坐标加密
aes-status: true
# 点选字体大小
font-size: 30
5.项目文件结构
其中,com.anji.captcha.service.CaptchaCacheService的内容是
com.anji.captcha.service.CaptchaCacheServiceRedisImpl的全限定名
com.anji.captcha.service.CaptchaCacheServiceRedisImpl
然后这里插一个小知识点,如果是分模块开发的,并且启动类不在该验证码模块中的话,记得去启动类上加@ComponentScan("com.anji.captcha")的注解,让spring容器能扫描到这些组件。
6.前端
6.1引入依赖
npm i --save-dev @types/crypto-js
6.2界面搭建
<div class="verify" v-if="enableCaptcha">
<Verify @success="login"
@error="loadVerify"
ref="verifyRef"
:mode="'pop'"
:captchaType="captchaType"
:imgSize="{ width: '330px', height: '155px' }">
</Verify>
</div>
<script setup lang="ts">
import Verify from '../components/verifition/Verify.vue';
const enableCaptcha = ref(false)
const verifyRef = useTemplateRef<InstanceType<typeof Verify>>("verifyRef")
const captchaType = ref<string>('blockPuzzle')
// 随机加载滑块/点击验证码
const loadVerify = () => {
setTimeout(() => {
captchaType.value = Math.random() < 0.5 ? 'blockPuzzle' : 'clickWord';
}, 700)
}
// 显示验证码
const showVerify = () => {
console.log('verifyRef.value:', verifyRef.value); // 添加日志
if (verifyRef.value) {
verifyRef.value.show();
} else {
console.error('verifyRef is undefined');
}
}
showVerify();
</script>
6.3下载相关文件
然后去https://gitee.com/anji-plus/captcha/tree/master/view/vue3/src/components这个网址把verifition的文件夹下载下来,粘贴到components目录下,我们需要对里面的文件做一点修改
6.4修改
在其api目录下的index.js中代码修改成下面这个样子,其中axiosInstance 的路径替换成自己项目中封装的axios所在的路径。相比于原来的,这里返回的数据是response.data。源码中返回的是整个response
对象。
import axiosInstance from "../../../plugins/axios.ts"
// 获取验证图片以及token
export async function reqGet(data) {
try {
const response = await axiosInstance({
url: '/captcha/get',
method: 'post',
data
})
return response.data
} catch (error) {
console.error("请求获取验证码出错:", error)
throw error
}
}
// 滑动或者点选验证
export async function reqCheck(data) {
try {
const response = await axiosInstance({
url: '/captcha/check',
method: 'post',
data
})
return response.data
} catch (error) {
console.error("请求验证出错:", error)
throw error
}
}
可能该文件夹下面的其他组件还会出现路径引用问题,修改一下就行
6.5路径问题
如果遇到明明就在那个路径下,vscode好提示找不到文件的话,可以在根目录下的vite-env.d.ts文件中添加以下代码
declare module "*.vue" {
import Vue from 'vue';
export default Vue;
}