行为验证
滑块图片验证
php
# 自定义参数
$params = [
'src' => '', // 背景图片,尺寸 340 * 191
'im_width' => 340, // 画布宽度
'im_height' => 251, // 画布高度
'im_type' => 'png', // png 默认 jpg quality 质量
'quality' => 80, // jpg quality 质量
'bg_width' => 340, // 背景宽度
'bg_height' => 191, // 背景高度
'slider_width' => 50, // 滑块宽度
'slider_height' => 50, // 滑块高度
'slider_border' => 2, // 滑块边框
'slider_bg' => 1, // 滑块背景数量
];
$type = 'slider';
/**
* 获取验证参数
* 内部使用了 laravel 的 cache 缓存,返回的是图片的 base64 、 缓存key 、滑块高度
* @param string $type 验证码类型
* @param array $params 验证码自定义参数
* @return arary
*/
$data = PosterManager::Captcha()->type($type)->config($params)->get();
$data = Captcha::type($type)->config($params)->get();
/**
* 验证
* 前端根据相关滑块操作进行处理, 返回x坐标,返回 true 则验证成功
* @param string $key 缓存key
* @param string|int $value 前端传回来的x坐标
* @param int $leeway 误差值
* @return boolean
*/
$res = PosterManager::Captcha()->type($type)->check($key, $value, $leeway);
$res = Captcha::type($type)->check($key, $value, $leeway);
旋转图片验证
php
# 自定义参数
$params = [
'src' => '', // 背景图片,尺寸 350 * 350 正方形都可
'im_width' => 350, // 画布宽度
'im_height' => 350, // 画布高度
'im_type' => 'png', // png 默认 jpg quality 质量
'quality' => 80, // jpg quality 质量
];
$type = 'rotate';
/**
* 获取验证参数
* 内部使用了 laravel 的 cache 缓存,返回的是图片的 base64 、 缓存key
* @param string $type 验证码类型
* @param array $params 验证码自定义参数
* @return arary
*/
$data = PosterManager::Captcha()->type($type)->config($params)->get();
$data = Captcha::type($type)->config($params)->get();
/**
* 验证
* 前端根据相关滑块操作进行处理, 返回x坐标,返回 true 则验证成功
* @param string $key 缓存key
* @param string|int $value 前端传回来的旋转角度
* @param int $leeway 误差值
* @return boolean
*/
$res = PosterManager::Captcha()->type($type)->check($key, $value, $leeway);
$res = Captcha::type($type)->check($key, $value, $leeway);
点击图片验证
php
# 自定义参数
$params = [
'src' => '',
'im_type' => 'png', // png 默认 jpg quality 质量
'quality' => 80, // jpg quality 质量
'font_family' => '', // 感谢站酷提供免费商用站酷库黑体、可自定义炫酷字体文件(绝对路径)
'contents' => '', // 自定义文字
'font_count' => 0, // 文字长度
'font_size' => 42, // 字体大小
'line_count' => 0, // 干扰线数量
'char_count' => 0, // 干扰字符数量
];
$type = 'click';
/**
* 获取验证参数
* 内部使用了 laravel 的 cache 缓存,返回的是图片的 base64 、 缓存key
* @param string $type 验证码类型
* @param array $params 验证码自定义参数
* @return arary
*/
$data = PosterManager::Captcha()->type($type)->config($params)->get();
$data = Captcha::type($type)->config($params)->get();
/**
* 验证
* 前端根据相关点击操作进行处理, 返回点击坐标数组,返回 true 则验证成功
* @param string $key 缓存key
* @param string|int|array $value 前端传回来的坐标数组
* @return boolean
*/
$res = PosterManager::Captcha()->type($type)->check($key, $value);
$res = Captcha::type($type)->check($key, $value);
手动输入验证
php
# 自定义参数
$params = [
'src' => '',
'im_width' => 256,
'im_height' => 64,
'im_type' => 'png', // png 默认 jpg quality 质量
'quality' => 80, // jpg quality 质量
'type' => 'number', // type = number 数字 alpha_num 字母和数字 math 计算 text 文字
'font_family' => '', // 可自定义炫酷字体文件
'font_size' => 32, // 字体大小
'font_count' => 4, // 字体长度
'line_count' => 5, // 干扰线数量
'char_count' => 10, // 干扰字符数量
];
$type = 'input';
/**
* 获取验证参数
* 内部使用了 laravel 的 cache 缓存,返回的是图片的 base64 、 缓存key
* @param string $type 验证码类型
* @param array $params 验证码自定义参数
* @return arary
*/
$data = PosterManager::Captcha()->type($type)->config($params)->get();
$data = Captcha::type($type)->config($params)->get();
/**
* 验证
* 前端根据相关输入, 返回输入结果,返回 true 则验证成功
* @param string $key 缓存key
* @param string|int|array $value 输入结果
* @return boolean
*/
$res = PosterManager::Captcha()->type($type)->check($key, $value);
$res = Captcha::type($type)->check($key, $value);
前端实现
参考仓库
gitee
github
js
直接引入js
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>图片验证DEMO</title>
</head>
<body>
<button type="button" onclick="captcha()">
验证
</button>
</body>
</html>
<script type="text/javascript" src="./slider/slider-min.js"></script>
滑块验证 js
javascript
<script type="text/javascript">
// 开始验证
function captcha(){
// 根据 poster 获取验证参数
Slider = new langSlider({
title: '滑块安全验证',
start: function(Slider) {
setTimeout(function(){
Slider.sliderStart({
sliderBg: './slider/img/slider.png',
sliderKey: '1212',
sliderY: 46
})
}, 1000);
},
check: function(sliderKey, sliderX, Slider) {
// 模拟调用验证接口
const check = () => {
const leeway = 5 // 误差值
const value = 208 // 正确值
if(value >= (sliderX - leeway) && value <= (sliderX + leeway)){
// 成功调用该方法
Slider.sliderSuccess()
} else {
// 错误调用该方法
// 模拟调用获取验证参数接口
setTimeout(function(){
Slider.sliderError({
sliderBg: './slider/img/slider.png',
sliderKey: '1212',
sliderY: 46
})
}, 1000);
}
}
setTimeout(function(){
check()
}, 1000)
},
refresh: function(Slider){
setTimeout(function(){
Slider.sliderRefresh({
sliderBg: './slider/img/slider.png',
sliderKey: '1212',
sliderY: 46
})
}, 1000);
},
})
}
</script>
vue
安装
bash
npm install @kkokk/captcha
yarn add @kkokk/captcha
卸载
bash
npm uninstall @kkokk/captcha
yarn remove @kkokk/captcha
引入
js
// main.js 引入
import Captcha from '@kkokk/captcha'
Vue.use(Captcha)
调用
vue
<template>
<div id="app">
<button @click="open">验证</button>
<slider-captcha
v-model="visible"
:options="options"
:loading="loading"
@check="check"
@close="close"
@refresh="getSliderOptions"
@error="getSliderOptions"
>
/** vue2 */
<span slot="title">自定义标题-安全验证</span>
<span slot="successText">自定义成功提示-登录中</span>
<span slot="errorText">自定义错误提示-是不是太难了换一个</span>
<span slot="tips">自定义提示拖动下方滑块完成拼图</span>
/** vue2 */
/** vue3 */
<template #title>自定义标题-安全验证</template>
<template #successText>自定义成功提示-登录中</template>
<template #errorText>自定义错误提示-是不是太难了换一个</template>
<template #tips>自定义提示拖动下方滑块完成拼图</template>
/** vue3 */
</slider-captcha>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
visible: false,
loading: false,
options: {}
}
},
methods: {
// 打开触发
open() {
this.visible = true
this.getSliderOptions()
},
// 验证
check(sliderKey, sliderX, done, error)
{
// 这里应该是验证是否成功的接口
if(sliderX > 208 - 5 && sliderX < 208 + 5) {
// 验证成功
done()
} else {
// 验证错误
error()
}
},
// 关闭触发
close() {
},
// 获取滑块验证参数
getSliderOptions()
{
this.loading = true
this.request({
type: 'get',
url: 'http://127.0.0.1:8111/',
success: (res) => {
this.options = {
sliderImg: res.img,
sliderKey: res.key,
sliderY: res.y
}
this.loading = false
}
})
},
// 封装一个简单请求接口,方便测试
request(obj) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
switch(obj.type) {
case 'get':
xhr.open('GET', obj.url, true);
xhr.onload = function() {
resolve(obj.success(JSON.parse(this.responseText)))
};
xhr.onError= function () {
reject(obj.error({
status: this.status,
statusText: xhr.statusText
}));
};
break;
case 'post':
xhr.open('POST', obj.url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
resolve(obj.success(JSON.parse(this.responseText)))
}
};
break;
}
xhr.send(JSON.stringify(obj.data));
});
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>