golang 调用 网易云 滑块验证码 demo

用法PHP示例主要代码

	session_start();
	$verifier = new NECaptchaVerifier(YIDUN_CAPTCHA_ID, new SecretPair(YIDUN_CAPTCHA_SECRET_ID, YIDUN_CAPTCHA_SECRET_KEY));
	$validate = $_POST['NECaptchaValidate']; // 获得验证码二次校验数据
	if(get_magic_quotes_gpc()){// PHP 5.4之前默认会将参数值里的 \ 转义成 \\,这里做一下反转义
        $validate = stripcslashes($validate);
    }
	$user = "{'user':123456}"; // 当前用户信息,值可为空

    /** @var $result bool */
	$result = $verifier->verify($validate, $user);

SDK接入文档: http://support.dun.163.com/documents/15588062143475712?docId=69218161355051008 

 

 github示例地址

git remote -v

origin https://github.com/yidun/captcha-php-demo (fetch)

origin https://github.com/yidun/captcha-php-demo (push)

改为golang版本

* SecretPair.go

package captcha

type SecretPair struct {
	SecretId string
	SecretKey string
}

func NewSecretPair(secretId string, secretKey string) *SecretPair {
	return &SecretPair{
		SecretId: secretId,
		SecretKey: secretKey,
	}
}

https://stackoverflow.com/questions/16895294/how-to-set-timeout-for-http-get-requests-in-golang

golang http client

timeout := time.Duration(5 * time.Second)
client := http.Client{
    Timeout: timeout,
}
client.Get(url)

* NECaptchaVerifier.go

package captcha

import (
	"bytes"
	"crypto/md5"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/Unknwon/com"
	"io/ioutil"
	"math/rand"
	"net/http"
	"sort"
	"strings"
	"time"
)

// @ref: https://github.com/yidun/captcha-php-demo
// @ref: http://support.dun.163.com/documents/15588062143475712?docId=69218161355051008
const (
	YIDUN_CAPTCHA_API_VERSION = "v2"
	YIDUN_CAPTCHA_API_TIMEOUT = 5
	YIDUN_CAPTCHA_API_URL     = "http://c.dun.163yun.com/api/v2/verify"
)

type NECaptchaVerifier struct {
	CaptchaID  string
	SecretPair SecretPair
}

type NEResponse struct {
	Msg    string `json:"msg"`
	Result bool   `json:"result"`
	Error  int    `json:"error"`
}

// 发起二次校验请求
// @param validate string 二次校验数据
// @param user 用户信息
func (this *NECaptchaVerifier) Verify(validate string, user string) (*NEResponse, error) {
	params := map[string]string{}
	params["captchaId"] = this.CaptchaID
	params["validate"] = validate
	params["user"] = user
	params["secretId"] = this.SecretPair.SecretId
	params["version"] = YIDUN_CAPTCHA_API_VERSION
	// time in millisecond
	params["timestamp"] = fmt.Sprintf("%d", time.Now().Unix()*1000)
	// random int
	rand.Seed(time.Now().UnixNano())
	params["nonce"] = fmt.Sprintf("%d", rand.Uint32())
	params["signature"] = genSignature(this.SecretPair.SecretKey, params)

	var result string
	var err error
	var ne NEResponse
	result, err = this.sendHttpResquest(params)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("send http request error: %s", err.Error()))
	}
	fmt.Println(result)

	// json deocode
	err = json.Unmarshal([]byte(result), &ne)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("json decode error: %s", err.Error()))
	}
	return &ne, err
}

// 计算参数签名
// @param secretKey 密钥对key
// @param params 请求参数
func genSignature(secretKey string, params map[string]string) string {
	var keys []string
	for key, _ := range params {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	buf := bytes.NewBufferString("")
	for _, key := range keys {
		buf.WriteString(key + params[key])
	}
	buf.WriteString(secretKey)
	fmt.Printf("signature=%s\n", buf.String())

	has := md5.Sum(buf.Bytes())
	return fmt.Sprintf("%x", has)
}

/**
 * 发送http请求
 * @param $params 请求参数
 */
func (*NECaptchaVerifier) sendHttpResquest(params map[string]string) (string, error) {
	client := &http.Client{
		Timeout: time.Second * YIDUN_CAPTCHA_API_TIMEOUT,
	}

	url := YIDUN_CAPTCHA_API_URL

	postString := http_build_query(params)
	req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(postString))
	if err != nil {
		return "", err
	}
	fmt.Printf("POST %s\n", url)
	fmt.Printf("[%s]\n", postString)
	for key, value := range params {
		fmt.Printf("%s = %s\n", key, value)
	}

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Length", fmt.Sprintf("%d", len(postString)))
	req.Header.Set("Upgrade-Insecure-Requests", "1")

	resp, err := client.Do(req)
	defer resp.Body.Close()

	if err != nil {
		return "", err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(body), nil
}

func http_build_query(params map[string]string) string {
	var a []string
	for k, v := range params {
		a = append(a, fmt.Sprintf("%s=%s", k, com.UrlEncode(v)))
	}
	return strings.Join(a, "&")
}

* SecretPair.go

package captcha

type SecretPair struct {
	SecretId  string
	SecretKey string
}

func NewSecretPair(secretId string, secretKey string) *SecretPair {
	return &SecretPair{
		SecretId:  secretId,
		SecretKey: secretKey,
	}
}

* Captcha.go

package captcha

import (
	"fmt"
	"github.com/kataras/iris/core/errors"
	"github.com/spf13/viper"
)

type Captcha struct {
	Validate string // $_POST["NECaptchaValidate"]
	Data     string // "{'user':123456}"
}

func (this *Captcha) Verify() (bool, error) {
	var verifier = NECaptchaVerifier{
		CaptchaID: viper.GetString("YIDUN_CAPTCHA_ID"),
		SecretPair: *NewSecretPair(
			viper.GetString("YIDUN_CAPTCHA_SECRET_ID"),
			viper.GetString("YIDUN_CAPTCHA_SECRET_KEY")),
	}
	fmt.Println(verifier)
	if len(this.Validate) < 1 {
		return false, errors.New("NECaptchaValidate can't be empty")
	}
	result, err := verifier.Verify(this.Validate, this.Data)
	fmt.Println(result)
	if err != nil {
		fmt.Println(err)
		return false, err
	}
	// {"msg":"PARAM_ERROR","result":false,"error":419}
	if !result.Result {
		return result.Result, errors.New(
			fmt.Sprintf("error:%d, msg:%s", result.Error, result.Msg))
	}
	// {"msg":OK, "result":true, "error"0}
	return result.Result, nil
}

 

* index.html


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>易盾验证码-DEMO</title>
    <!-- 演示用js/css,非组件依赖 -->
    <link href='//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.css' rel='stylesheet'>
</head>
<body>
<!-- <form style="max-width: 320px; margin: 120px auto;" action="http://192.168.4.157:8060/v1/testCaptcha" method="post"> -->
<form style="max-width: 320px; margin: 120px auto;" action="http://192.168.4.157:8060/v1/validate/getcode" method="post">
    <h2 class="form-signin-heading">易盾验证码</h2>
    <input type="text" class="form-control" name="mobilenumber" placeholder="手机号码" value="">
    <div style="margin: 10px auto;" id="captcha_div"></div> <!-- 验证码容器元素定义 -->
    <button class="btn btn-lg btn-primary btn-block" type="submit" id="submit-btn">登录</button>
</form>
<script src="//cstaticdun.126.net/load.min.js"></script>
<script> // 验证码组件初始化
initNECaptcha({
    captchaId: 'd094d0????????????????', // <-- 这里填入在易盾官网申请的验证码id
    element: '#captcha_div',
    mode: 'float',
    width: '320px',
    onVerify: function(err, ret){
        if(!err){
            // ret['validate'] 获取二次校验数据
        }
        console.log(ret)
    }
}, function (instance) {
    // 初始化成功后得到验证实例instance,可以调用实例的方法
    console.log(instance)
}, function (err) {
    // 初始化失败后触发该函数,err对象描述当前错误信息
    console.log(err)
});


</script>
</body>
</html>
php -S 0.0.0.0:8082

浏览器访问 http://127.0.0.1:8082

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fareast_mzh

打赏个金币

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值