顶象滑块验证码

一、服务接入流程

官网

服务接入流程

二、无感验证后端接入(业务应用集成)

  • 访问顶象官网,注册账号后登录控制台,访问“无感验证”模块,申请开通后系统会分配一个唯一的AppId、AppSecret。
  • 当用户滑动验证码通过后,验证码服务会生成一个token,用户的业务请求带上这个验证码token,业务系统再调用后台 SDK 验证token的有效性。
               |
|    用户业务请求        |  ----> | 业务系统      |  ----> | |             验证码服务
  (请求带上验证码token)     |      (获取token,调用验证码接口)     |  |     (校验token有效性)   |
 

顶象提供后端SDK来校验token是否合法 ,目前支持JAVA版、PHP版、C#版、Python版。

token验证api返回数据
字段名 数据类型 描述
success Boolean 是否成功,true/false
msg String 错误信息
ip String token产生时,客户端的ip
code String 错误code
错误code说明
code 描述
1001 错误的APPID
1002 签名错误,请核对APPID和APPSECRET是否正确
1003 token不合法或者已经过期(token是一次性使用并且只有两分钟有效期)
1004 参数错误,请核对后端使用的APPID是否和前端页面一致
1005 verifyToken传入ip时,校验不通过,即token产生的ip和业务请求ip不一致

三、后端实现

# CaptchaResponse.py (第三方)
class CaptchaResponse:
    result = False
    serverStatus = ""

    def __init__(self, result, serverStatus):
        self.result = result
        self.serverStatus = serverStatus

    def setResult(self, result):
        self.result = result

    def setServerStatus(self, serverStatus):
        self.serverStatus = serverStatus

# CaptchaClient.py (第三方)
from urllib import request
import hashlib
import json
from new.CaptchaResponse import CaptchaResponse


class CaptchaClient:
    requestUrl = "https://cap.dingxiang-inc.com/api/tokenVerify"

    timeout = 2
    response = None

    def __init__(self, appId, appSecret):
        self.appId = appId
        self.appSecret = appSecret

    def setTimeOut(self, timeOut):
        self.timeout = timeOut

    def setCaptchaUrl(self, url):
        self.requestUrl = url

    def checkToken(self, token):
        print(len(token) > 1024)
        captchaResponse = CaptchaResponse(False, "")
        """
        if (self.appId == "" or (self.appId is None) or self.appSecret == ""
                or (self.appSecret is None) or token == "" or (token is None)
                or not (len(token) > 1024)):
        
        """
        if (self.appId == "" or (self.appId is None) or self.appSecret == ""
                or (self.appSecret is None) or token == "" or (token is None)
                or not (len(token) > 205)):
            captchaResponse.setServerStatus("参数错误")
            return captchaResponse.__dict__

        arr = token.split(":")
        print(arr)
        constId = ""
        if len(arr) == 2:
            constId = arr[1]
        str_key = self.appSecret + arr[0] + self.appSecret
        sign = hashlib.md5(str(str_key).encode("utf8")).hexdigest()
        req_url = self.requestUrl + '?appKey=' + self.appId + '&token=' + arr[
            0] + '&constId=' + constId + "&sign=" + sign

        try:
            # self.response = urllib2.urlopen(req_url, timeout=self.timeout)
            self.response = request.urlopen(req_url, timeout=self.timeout)

            # self.response = requests.get(req_url, timeout=self.timeout)
            print(self.response.code)
            if self.response.code == 200:
                result = self.response.read()
                result = json.loads(result)
                captchaResponse.setServerStatus("SERVER_SUCCESS")
                captchaResponse.setResult(result["success"])
            else:
                captchaResponse.setResult(True)
                captchaResponse.setServerStatus("server error: status=" + str(self.response.code))
            return captchaResponse.__dict__
        except Exception as e:
            captchaResponse.setResult(True)
            captchaResponse.setServerStatus("server error:" + e)
            return captchaResponse.__dict__
        finally:
            self.close(self.response)

    def close(self, response):
        try:
            if response != None:
                response.close()
                del response
        except Exception as e:
            print("close response error:" + e.message)

            
# TokenDemo.py(自定义测试)           
from new.CaptchaClient import CaptchaClient
APP_ID = '693d3ef199e411d0ed62cb2a87d8bdde'
APP_SECRET = '5eea7b131502eece01409d8bd358f0d5'
if __name__ == '__main__':
    captchaClient = CaptchaClient(APP_ID, APP_SECRET)
    captchaClient.setTimeOut(2)
    # 设置超时时间,默认2秒
    # captchaClient.setCaptchaUrl("http://cap.dingxiang-inc.com/api/tokenVerify")
    # 特殊情况可以额外指定服务器,默认情况下不需要设置

    # 只能使用一次
    token = 'token:11159D5F8D540AA73D207C5FF53EAD7906F1A01D3D9D63E044F1DBE3CE6FB117ECB81B1038A6755D455A0059164BC0D61462F6D0E55910FA0E27B1BF7F8FDA610512217CBC50B81B3A3DDDD2F0F06CD8:5df10ea2jLv7WP9YbNEIfgn3xFpmnRAMb818FAu1'
    print(len(token))
    response = captchaClient.checkToken(token)
    print(response)
    # print("serverStatus", response['serverStatus'])
    # 确保验证状态是SERVER_SUCCESS,SDK中有容错机制,在网络出现异常的情况会返回通过
    # print(response['result'])
    if response.get('result') and response.get('serverStatus') == 'SERVER_SUCCESS':
        # token验证通过,继续其他流程
        print('成功')
        pass
    else:
        # token验证失败,业务系统可以直接阻断该次请求或者继续弹验证码
        print("失败")
        pass

四、前端应用

文档说明

滑块类型

常规参数

初始化时有若干参数,其中 appId 是必填的。

参数名 必填 类型 说明
appId String 当前应用的唯一标识
type String 类型,目前只有一个选项 basic,默认值为 basic
style String 样式,可选项有 embed(默认)、inlinepopuponeclick 四种,具体效果可参见线上demo
inlineFloatPosition String 浮动层位置,仅当 style 的值为 inline 时有效,可选项有 up(默认)、down 两种,具体效果可参见线上demo
oneClickFloatPosition string 浮动层位置,仅当 style 的值为 oneclick 时有效,可选项有 up,当style值为oneclick且不传此参数,默认为弹出形式。
width Number 控件(滑动条)宽度,单位为像素,默认为 300
language String 语言,可选项有 cn(默认,中文)、en(英文)。
success Function 验证成功时的回调函数,会传入一个参数,值为本次验证的 token:constId,接入方需在后续的验证中传回此项值。注:此回调函数包含无感验证成功及滑动验证成功。
fail Function 验证失败时的回调函数,会传入一个参数,值为出错信息。

方法

验证码实例具备以下方法:

  • reload() 重置当前验证码

    示例:

     myCaptcha.reload()
    
  • show() 显示当前验证码。

    stylepopup 的验证码默认是隐藏的,需要接入方根据页面逻辑调用 show() 方法将其显示。

    示例:

     myCaptcha.show()
    
  • hide() 隐藏当前验证码

    示例:

     myCaptcha.hide()
    
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {#    验证码滑块#}
    <script src="https://cdn.dingxiang-inc.com/ctu-group/captcha-ui/index.js"></script>
    <style>
        .f {
            height: 500px;
        }

        .tan {
            width: 600px;
            margin: 0 auto;
            line-height: 500px;
            font: normal 60px 微软雅黑;
            text-align: center;
        }

        .tan:hover {
            border-radius: 5px;
            border: 1px black solid;
            box-shadow: 4px 6px WindowFrame;
        }
    </style>
</head>
<body>
<div id="c1"></div>
<div class="f">
    <div id="btn-popup" class="tan">弹出</div>
</div>

</body>
<script>

    var myCaptcha = _dx.Captcha(document.getElementById('c1'), {
        {#appId: 'appId', //appId,在控制台中“应用管理”或“应用配置”模块获取#}
        appId: '693d3ef199e411d0ed62cb2a87d8bdde',
        style: 'popup', // 类型

        success: function (token) {
            console.log('token:', token);
            myCaptcha.hide();
            setTimeout(function () {
                myCaptcha.reload();

            }, 1000);

        },
        fail: function (error) {
            console.log(error);
            myCaptcha.reload();
        },

    });
    document.getElementById('btn-popup').onclick = function () {
        myCaptcha.show();
    }
</script>
</html>
posted @ 2019-12-12 23:51  RandySun  阅读(5155)  评论(1编辑  收藏  举报