如對接入流程存在疑問,參見快速接入


前端接入


web


兼容性


支持 Chrome、IE9+、360、騰訊、搜狗、Safari、Firefox、Opera;主流手機瀏覽器


引入初始化 SDK JS


<script src="http://www.ssjdyy2.com/static/official/js/libs/riddler-sdk-0.2.2.js?t=20210804"></script>


注:IE9+需要在 SDK 之前額外引入 polyfill,示例如下


<script src="https://cdn.bootcss.com/babel-polyfill/7.4.3/polyfill.min.js"></script>


配置驗證對象



new YpRiddler(options)
options 對象為配置對象,以下為配置參數(shù):

參數(shù)

類型

必填

備注

onSuccess

function(validInfo:object, close:function)

Y

監(jiān)聽驗證成功事件。validInfo:驗證成功返回參數(shù)(token,authenticate);close:關(guān)閉驗證窗口

appId

string

Y

應用標識。captchaId

version

string

Y

接口版本號

container

HTMLElement

Y

驗證邏輯綁定的元素

noButton

boolean

F

是否在 container 內(nèi)渲染按鈕,當 mode 不為 flat 時有效

mode

string

F

UI 接入方式。flat-直接嵌入,float-浮動,dialog-對話框,external-外置滑動(拖動滑塊時才浮現(xiàn)驗證圖片,僅適用于滑動拼圖驗證) 默認 dialog

onError

function

F

驗證異常處理器。即當云片驗證服務(wù)出現(xiàn)異常時,可以在此回調(diào)上處理,比如,不使用驗證,或者,使用圖片驗證服務(wù)等。

onFail

function(code:int, msg:string, retry:function)

F

用戶驗證失敗處理器, code: 錯誤碼,msg: 錯誤信息,retry: 重試驗證邏輯。默認實現(xiàn)為重新驗證一次。

beforeStart

function(next:function)

F

進入驗證邏輯前的勾子。next: 繼續(xù)執(zhí)行后續(xù)邏輯

expired

int

F

請求過期時限。單位秒,默認 30

jsonpField

string

F

jsonp 處理器名。默認為 ypjsonp

rsaPublicKey

string

F

加密公鑰。如非異常情況則無需設(shè)置

hosts

string

F

驗證服務(wù)器地址。如非異常情況則無需設(shè)置

winWidth

number/string

F

窗口寬度。寬度最小 230px: 兩種方式:1. 純數(shù)字格式,單位 px. 默認 500; 2. 百分比格式, 比如 80%,表示相對當前瀏覽器可視區(qū)域?qū)挾鹊陌俜直取2恍∮?230px

lang

string

F

支持語言,默認簡體中文。zh-cn(簡體中文)、en(英文)

langPack

object

F

外部導入所需設(shè)置語言文案。需按指定格式設(shè)置對象導入,當外部導入語言包時,lang 設(shè)置會自動失效


winWidth 窗口寬度配置


// 設(shè)置窗口寬度為固定值(px)
new YpRiddler({
  ...
  winWidth: '500'
  ...
})

// 設(shè)置窗口寬度為屏幕寬度的百分比(窗口寬度winWidth = 屏幕寬度 * %)
new YpRiddler({
  ...
  winWidth: '30%'
  ...
})


lang 配置(可選)



系統(tǒng)默認支持中文,如需要替換其他語言請進行如下配置。目前支持的語言有:簡體中文、英文。
如果需要設(shè)置文案的語言,可通過外部文件,按指定格式設(shè)置文案內(nèi)容,然后在 options 配置項中通過 langPack 傳入語言對象(object)即可。


// 語言模版
const LANG_OTHER = {
  'YPcaptcha_01': '請點擊按鈕開始驗證',
  'YPcaptcha_02': '請按順序點擊:',
  'YPcaptcha_03': '向右拖動滑塊填充拼圖',
  'YPcaptcha_04': '驗證失敗,請重試',
  'YPcaptcha_05': '驗證成功'
}
new YpRiddler({
  ...
  langPack: LANG_OTHER
  ...
})


Demo (Html)


<html>

<head>
    <!--依賴-->
    <script src="http://www.ssjdyy2.com/static/official/js/libs/riddler-sdk-0.2.2.js?t=20210720"></script>
    <script>
        window.onload = function () {
            // 初始化
            new YpRiddler({
                expired: 10,
                mode: 'dialog',
                winWidth: 500,
                lang: 'zh-cn', // 界面語言, 目前支持: 中文簡體 zh-cn, 英語 en
                // langPack: LANG_OTHER, // 你可以通過該參數(shù)自定義語言包, 其優(yōu)先級高于lang
                container: document.getElementById('cbox'),
                appId: 'your-app-id',
                version: 'v1',
                onError: function (param) {
                        if (!param.code) {
                            console.error('錯誤請求');
                        }
                        else if (parseInt(param.code / 100) == 5) {
                            // 服務(wù)不可用時,開發(fā)者可采取替代方案,詳見 “get 接口響應碼釋義”
                            console.error('驗證服務(wù)暫不可用');
                        }
                        else if (param.code == 429) {
                            console.warn('請求過于頻繁,請稍后再試');
                        }
                        else if (param.code == 403) {
                            console.warn('請求受限,請稍后再試');
                        }
                        else if (param.code == 400) {
                            console.warn('非法請求,請檢查參數(shù)');
                        }
                    // 異常回調(diào)
                    console.error('驗證服務(wù)異常')
                },
                onSuccess: function (validInfo, close, useDefaultSuccess) {
                    // 成功回調(diào)
                    alert('驗證通過! token=' + validInfo.token + ', authenticate=' + validInfo.authenticate)
                    // 驗證成功默認樣式
                    useDefaultSuccess(true)
                    close()
                },
                onFail: function (code, msg, retry) {
                    // 失敗回調(diào)
                    alert('出錯啦:' + msg + ' code: ' + code)
                    retry()
                },
                beforeStart: function (next) {
                    console.log('驗證馬上開始')
                    next()
                },
                onExit: function () {
                    // 退出驗證 (僅限dialog模式有效)
                    console.log('退出驗證')
                }
            })
        }
    </script>
</head>

<body>
    <div id="cbox"></div>
</body>

</html>


Demo (React)


在@/public/index.html的header元素中加入:


<script src="https://cdn.bootcss.com/babel-polyfill/7.4.3/polyfill.min.js"></script>
<script src="http://www.ssjdyy2.com/static/official/js/libs/riddler-sdk-0.2.2.js?t=20210720"></script>


使用方法如下:


import React from 'react'

// 如下配置僅作為示例,具體可參考'配置驗證對象'小節(jié)
const initYpRiddler = () => {
  new window.YpRiddler({
    appId: '請在這里填入實際的appId',
    expired: 10,
    mode: 'dialog',
    winWidth: 500,
    lang: 'zh-cn',
    container: document.getElementById('cbox'),
    version: 'v1',
    onSuccess: function (validInfo, close, useDefaultSuccess) {
      alert(
        '驗證通過! token=' +
          validInfo.token +
          ', authenticate=' +
          validInfo.authenticate
      )
      useDefaultSuccess.call(null, true)
      close()
    },
    onFail: function (code, msg, retry) {
      alert('出錯啦:' + msg + ' code: ' + code)
      retry()
    },
    beforeStart: function (next) {
      console.log('驗證馬上開始')
      next()
    },
    onExit: function () {
      console.log('退出驗證')
    },
  })
}

class App extends React.Component {
  componentDidMount() {
    initYpRiddler() // 在需要展示行為驗證的時候,調(diào)用該方法
  }
  render() {
    <!-- id名稱、樣式均可根據(jù)需要進行設(shè)置 -->
    return <div id='cbox' style={{ width: '400px' }}></div>
  }
}

export default App


Demo (Vue)


在@/public/index.html的header元素中加入:


<script src="https://cdn.bootcss.com/babel-polyfill/7.4.3/polyfill.min.js"></script>
<script src="http://www.ssjdyy2.com/static/official/js/libs/riddler-sdk-0.2.2.js?t=20210720"></script>


使用方法如下:


<template>
  <!-- id名稱、樣式均可根據(jù)需要進行設(shè)置 -->
  <div id="cbox" style="width: 300px"></div>
</template>

<script>
  export default {
    name: 'App',
    methods: {
      // 如下配置僅作為示例,具體可參考'配置驗證對象'小節(jié)
      initYpRiddler() {
        new window.YpRiddler({
          appId: '6bb8b48f5e024ae3b7347be171b27ec9',
          expired: 10,
          mode: 'dialog',
          winWidth: 500,
          lang: 'zh-cn',
          container: document.getElementById('cbox'),
          version: 'v1',
          onSuccess: function (validInfo, close, useDefaultSuccess) {
            alert(
              '驗證通過! token=' +
                validInfo.token +
                ', authenticate=' +
                validInfo.authenticate
            )
            useDefaultSuccess.call(null, true)
            close()
          },
          onFail: function (code, msg, retry) {
            alert('出錯啦:' + msg + ' code: ' + code)
            retry()
          },
          beforeStart: function (next) {
            console.log('驗證馬上開始')
            next()
          },
          onExit: function () {
            console.log('退出驗證')
          }
        })
      }
    },
    mounted() {
      this.initYpRiddler() // 在需要展示行為驗證的時候,調(diào)用該方法
    }
  }
</script>


接入成功樣例


前端接入完成后,通過谷歌瀏覽器的 Network 查看請求記錄,verify 請求會返回兩個參數(shù):authenticatetoken。


后端接入


接口名稱


二次驗證接口


接口地址


https://captcha.yunpian.com/v1/api/authenticate


請求


  • 請求方式:POST
  • 請求類型:application/x-www-form-urlencoded


請求參數(shù)

參數(shù)

類型

必填

備注

captchaId

string

Y

驗證應用 id,對應用戶后臺分配的 APPID

token

string

Y

前端從 verfiy 接口獲取的 token,token 作為一次驗證的標志。

authenticate

string

Y

前端從 verfiy 接口驗證通過后,返回的參數(shù)

secretId

string

Y

驗證應用密鑰 id

version

string

Y

版本,固定值 1.0

user

string

F

可選值,接入方用戶標志,如擔心信息泄露,可采用摘要方式給出。

timestamp

string

Y

當前時間戳的毫秒值,如 1541064141441

nonce

string

Y

隨機正整數(shù), 在 1-99999 之間,與 timestamp 配合可以防止消息重放

signature

string

Y

簽名信息,見簽名計算方法


支持的語言及請求示例


Java 請求示例


import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;

/**
 * A demo for YunPian CAPTCHA authenticate API
 */
public class AuthenticateDemo {

  private static String AUTH_URL = "https://captcha.yunpian.com/v1/api/authenticate";

  public static void main(String[] args) throws IOException, URISyntaxException {
    Map<String, String> paramMap = new HashMap<>();
    // replace the following "{example}"s with actual values
    paramMap.put("captchaId", "{APPID}");
    paramMap.put("secretId", "{secretId}");
    paramMap.put("token", "{token}");
    paramMap.put("authenticate", "{authenticate}");
    paramMap.put("version", "1.0");
    paramMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
    paramMap.put("nonce", String.valueOf(new Random().nextInt(99999)));
    paramMap.put("user", "{user}"); // user is optional

    String signature = genSignature("{secretKey}", paramMap);
    paramMap.put("signature", signature);

    StringBuilder sb = new StringBuilder();
    PostMethod postMethod = new PostMethod(AUTH_URL);
    postMethod.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    paramMap.forEach((k, v) -> {
      postMethod.addParameter(k, v);
    });
    HttpClient httpClient = new HttpClient();
    int status = httpClient.executeMethod(postMethod);
    String responseBodyAsString = postMethod.getResponseBodyAsString();
    System.out.println(responseBodyAsString);
  }

  // generate signature
  private static String genSignature(String secretKey, Map<String, String> params) {
    String[] keys = params.keySet().toArray(new String[0]);
    Arrays.sort(keys);
    StringBuilder sb = new StringBuilder();
    for (String key : keys) {
      sb.append(key).append(params.get(key));
    }
    sb.append(secretKey);
    return DigestUtils.md5Hex(sb.toString());
  }
}


C#請求示例


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace ConsoleApp1
{
    /// A demo for YunPian CAPTCHA authenticate API
    class AuthenticateDemo
    {
        protected const string AUTH_URL = "https://captcha.yunpian.com/v1/api/authenticate";
        protected const string VERSION = "1.0";
        protected const int MAX_NONCE = 99999;

        static void Main(string[] args)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            // replace the following "{example}"s with actual values!!!
            parameters.Add("captchaId", "{APPID}");
            parameters.Add("secretId", "{secretId}");
            parameters.Add("token", "{token}");
            parameters.Add("authenticate", "{authenticate}");
            parameters.Add("version", VERSION);
            parameters.Add("timestamp", GetCurrentTimeMillis());
            parameters.Add("nonce", GetNonce().ToString());
            //parameters.Add("user", "{user}"); // user is optional

            // generate signature
            string sign = GenSignature("{secretKey}", parameters);
            parameters.Add("signature", sign);

            // authenticate
            string retString = PostAuthData(parameters);
            Console.WriteLine(retString);
        }

        // post authenticate data
        public static string PostAuthData(Dictionary<string, string> parameters)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in parameters)
            {
                if (sb.Length > 0)
                    sb.Append("&");
                sb.Append(item.Key + "=" + HttpUtility.UrlEncode(item.Value, System.Text.Encoding.UTF8));
            }
            string data = sb.ToString();

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AUTH_URL);
            request.Timeout = 30 * 1000;

            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = Encoding.UTF8.GetByteCount(data);

            Stream myRequestStream = request.GetRequestStream();
            byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(data);
            myRequestStream.Write(requestBytes, 0, requestBytes.Length);
            myRequestStream.Close();

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();

            return retString;
        }
        // generate signature
        public static String GenSignature(String secretKey, Dictionary<String, String> parameters)
        {
            parameters = parameters.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
            StringBuilder builder = new StringBuilder();
            foreach (KeyValuePair<String, String> kv in parameters)
            {
                builder.Append(kv.Key).Append(kv.Value);
            }
            builder.Append(secretKey);
            String tmp = builder.ToString();
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] result = md5.ComputeHash(Encoding.UTF8.GetBytes(tmp));
            builder.Clear();
            foreach (byte b in result)
            {
                builder.Append(b.ToString("x2"));
            }
            return builder.ToString();
        }

        private static int GetNonce()
        {
            Random r = new Random();
            int n = r.Next(1, MAX_NONCE);
            return n;
        }

        private static String GetCurrentTimeMillis()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalMilliseconds).ToString();
        }
    }
}


PHP 請求示例


<?php
$params = array();
$params["authenticate"] ="{authenticate}";//用戶驗證通過后,返回的參數(shù)
$params["token"] ="{token}";//前端返回的 token
$params["captchaId"] ="{APPID}";//驗證應用 id
$params["secretId"] ="{secretId}";//驗證應用 secretId
$secretKey = "{secretKey}";//驗證應用 secretKey
$params["version"] = "1.0";//版本,固定值1.0
$params["timestamp"] = sprintf("%d", round(microtime(true)*1000));// 當前時間戳的毫秒值,如1541064141441
$params["nonce"] = sprintf("%d", rand(1,99999)); //隨機正整數(shù), 在 1-99999 之間
ksort($params); // 參數(shù)排序
$buff="";

foreach($params as $key=>$value){
        $buff .=$key;
        $buff .=$value;
}
$buff .= $secretKey;
//print_r($buff);
$signature=md5($buff);
$params["signature"] =$signature ;//簽名信息,見簽名計算方法

$url="https://captcha.yunpian.com/v1/api/authenticate";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
/* 設(shè)置返回結(jié)果為流 */
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
/* 設(shè)置超時時間*/
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
/* 設(shè)置通信方式 */
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
$result = curl_exec($ch);
var_dump($result);


Python 請求示例


import random
import time
import hashlib
import requests

authenticate = '{authenticate}'
secretKey = '{secretKey}'
token = '{token}'
captchaId = '{APPID}'
secretId = '{secretId}'

data = {
  'authenticate': authenticate,
  'captchaId': APPID,
  'nonce': str(random.randint(10000, 99999)),
  'secretId': secretId,
  'timestamp': str(time.time()).split('.')[0],
  'token': token,
  'version': '1.0'
}
print '%s: %s' % ('data', data)


sign_str = ''
items = sorted(data.items(), key=lambda d:d[0])

for item in items:
  sign_str += '%s%s' % (item[0],item[1])

sign_str += secretKey
print '%s: %s' % ('sign_str', sign_str)

signature = hashlib.md5(sign_str).hexdigest().lower()
data['signature'] = signature

print '%s: %s' % ('data', data)

url = 'https://captcha.yunpian.com/v1/api/authenticate'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}

r = requests.post(url, data=data, headers=headers)

print r.text


補充說明:


1、簽名計算方法


  1. 第一步:對所有請求參數(shù)(不包括 signature 參數(shù)),按照參數(shù)名 ASCII 碼表升序順序排序。如:foo=1, bar=2, foo_bar=3, baz=4 排序后的順序是 bar=2, baz=4, foo=1, foo_bar=3 。
  1. 第二步:將排序好的參數(shù)名和參數(shù)值構(gòu)造成字符串,格式為:key1+value1+key2+value2… 。根據(jù)上面的示例得到的構(gòu)造結(jié)果為:bar2baz4foo1foo_bar3 。
  1. 第三步:選擇與 secretId 配對的 secretKey ,加到上一步構(gòu)造好的參數(shù)字符串之后,如 secretKey=e3da918313c14ea8b25db31f01263f80?,則最后的參數(shù)字符串為 ?bar2barz4foo1foo_bar3e3da918313c14ea8b25db31f01263f80。
  1. 第四步:把 3 步驟拼裝好的字符串采用 utf-8 編碼,使用 MD5 算法對字符串進行摘要,計算得到 signature 參數(shù)值,將其加入到接口請求參數(shù)中即可。MD5 是 128 位長度的摘要算法,用 16 進制表示,一個十六進制的字符能表示 4 個位,所以簽名后的字符串長度固定為 32 位十六進制字符。上述簽名的結(jié)果為:59db908f26fb997c30b32ddb911485c2。


/**
 * 生成簽名信息
 * @param secretKey 應用私鑰
 * @param params 接口請求參數(shù)名和參數(shù)值map,不包括signature參數(shù)名
 * @return
 */
public static String genSignature(String secretKey, Map<String, String> params){
    // 1. 參數(shù)名按照ASCII碼表升序排序
    String[] keys = params.keySet().toArray(new String[0]);
    Arrays.sort(keys);

    // 2. 按照排序拼接參數(shù)名與參數(shù)值
    StringBuilder sb = new StringBuilder();
    for (String key : keys) {
        sb.append(key).append(params.get(key));
    }
    // 3. 將secretKey拼接到最后
    sb.append(secretKey);

    // 4. MD5是128位長度的摘要算法,轉(zhuǎn)換為十六進制之后長度為32字符
    return DigestUtils.md5Hex(sb.toString().getBytes("UTF-8"));
}


2、響應碼釋義


前端相關(guān)響應碼


verify 接口響應碼釋義

響應碼

錯誤信息

具體描述

0

ok

驗證通過

1

bad request

驗證請求數(shù)據(jù)缺失或格式有誤

2

verify fail

驗證不通過

400

param_invalid

請求參數(shù)錯誤,檢查 i k 參數(shù)

400

captcha_id_invalid

APPID 不存在

429

too many requests

請求過于頻繁,請稍后再試

500

server_error

服務(wù)異常


get 接口響應碼釋義

響應碼

錯誤信息

具體描述

0

ok

獲取驗證圖片成功

400

param_invalid

請求參數(shù)錯誤,檢查 i k 參數(shù)

403

forbidden request

異常請求,已攔截,需要一段時間才允許恢復訪問,可能是訪問過于頻繁導致

400

captcha_id_invalid

APPID 不存在

429

too many requests

請求過于頻繁,請稍后再試

500

server_error

服務(wù)異常

531

server_reject

拒絕提供服務(wù),例如驗證量超過套餐額度后,可能會拒絕服務(wù),同其他5xx錯誤碼一樣,應考慮回退方案


后端相關(guān)響應碼


響應參數(shù)

參數(shù)

類型

必填

備注

code

int

Y

成功為 0,非 0 為異常信息,詳見下方“二次驗證接口響應碼釋義”

msg

string

Y

錯誤描述信息


二次驗證接口響應碼釋義

響應碼

錯誤信息

具體描述

0

ok

二次驗證通過

400

validate_fail

二次驗證不通過

400

signature_invalid

簽名校驗失敗

400

param_invalid

請求參數(shù)錯誤,檢查 i k 參數(shù)

400

captcha_id_invalid

APPID 不存在

400

re_authenticate

重復的authenticate和token

429

too many requests

請求過于頻繁,請稍后再試

500

server_error

服務(wù)異常

特黄人与动人物视频A级毛片,久久婷婷五月色综合蜜芽,亚洲AV永久无码区成人网站,精品无码成人网站久久久久久无码 ,日本动漫爆乳H动漫啪啪免费,成年女人毛片免费视频喷潮,一本之道高清在线观看免费,一级A片无遮挡,18禁美女挤奶水视频免费,欧美牲交A欧美牲交AⅤ电影