滑块验证图片
演示
滑块前端演示 kkokk.github.io/captcha/
使用文档
开源仓库
gitee
github
后端
安装
composer require kkokk/poster
更新
composer update kkokk/poster
演示
use Kkokk\Poster\Facades\Captcha;
use Kkokk\Poster\Exception\PosterException;
try {
# 滑块自定义参数
$params = [
'src' => '', // 背景图片,尺寸 340 * 191
'im_width' => 340, // 画布宽度
'im_height' => 251, // 画布高度
'bg_width' => 340, // 背景宽度
'bg_height' => 191, // 背景高度
'slider_width' => 50, // 滑块宽度
'slider_height' => 50, // 滑块高度
'slider_border' => 2, // 滑块边框
];
$type = 'slider';
/**
* 获取滑块验证参数
* 内部使用了 laravel 的 cache 缓存,返回的是图片的 base64 、 缓存key 、滑块高度
* @param string $type 验证码类型
* @param array $params 验证码自定义参数
* @return arary
*/
$data = Captcha::type($type)->config($params)->get();
/**
* 验证滑块
* 前端根据相关滑块操作进行处理, 返回x坐标,返回 true 则验证成功
* @param string $key 缓存key
* @param string|int $value 前端传回来的x坐标
* @param int $leeway 误差值
* @return boolean
*/
$res = Captcha::type($type)->check($key, $value, $leeway);
} catch (PosterException $e) {
print_r($e->getMessage())
}
js
<!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>
<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
# 安装
npm install @kkokk/captcha
yarn add @kkokk/captcha
# 卸载
npm uninstall @kkokk/captcha
yarn remove @kkokk/captcha
// main.js 引入
import Captcha from "@kkokk/captcha"
Vue.use(Captcha)
<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"
>
<span slot="title">自定义标题-安全验证</span>
<span slot="successText">自定义成功提示-登录中</span>
<span slot="errorText">自定义错误提示-是不是太难了换一个</span>
<span slot="tips">自定义提示拖动下方滑块完成拼图</span>
</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>
示例
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 2年前 自动加精
:+1:
:+1:
浪哥牛比
自己写的?
谢谢!收藏了
上周发现的,今天引入美滋滋啊。去掉了原来的验证码舒服。 :smirk: