滑块验证图片

演示

滑块前端演示 kkokk.github.io/captcha/
使用文档

开源仓库

gitee

poster 文档

captcha js 文档

captcha vue 文档

github

poster 文档

captcha js 文档

captcha vue 文档

后端

安装
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 协议》,转载必须注明作者和本文链接
本帖由系统于 1年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 12

浪哥牛比

1年前 评论
kkokk (楼主) 1年前

自己写的?

1年前 评论
kkokk (楼主) 1年前
bishi123 (作者) 1年前
kkokk (楼主) 1年前

上周发现的,今天引入美滋滋啊。去掉了原来的验证码舒服。 :smirk:

10个月前 评论
kkokk (楼主) 10个月前
chenweil (作者) 10个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!