1. 前端部分(可以直接copy 网易易盾的官方文档) 修改一下 接口指向 nodejs
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>验证码示例-智能无感知bind模式</title> </head> <body> <form action="/login" method="post"> <input type="text" name="username" placeholder="用户名" /> <input type="password" name="password" placeholder="密码" /> <input type="hidden" name="captchaId" value="从易盾申请的captchaId" /> <div id="captcha"></div> <!-- 验证码容器元素 --> <button type="submit" id="submit-btn">登录</button> </form> <script charset="UTF-8" type="text/javascript" src="http://cstaticdun.126.net/load.min.js" ></script> <script> var captchaIns initNECaptcha( { element: '#captcha', captchaId: '49fa346201934f81bf866dca2b7f42c8', mode: 'bind', // 仅智能无感知验证码时,mode 才能设置为 bind width: '320px', //enableClose: true, // 由业务方控制验证码弹框关闭 onVerify: function(err, ret) { // 用户验证码验证成功后,进行实际的提交行为 // todo if (err) console.log(err) if (!err) { request(ret.validate) console.log(ret.validate) } } }, function(instance) { // 初始化成功后得到验证实例instance,可以调用实例的方法 captchaIns = instance }, function(err) { // 初始化失败后触发该函数,err对象描述当前错误信息 } ) // 监听需要绑定的 button 的点击事件,手动调用实例的verify方法来验证 document .getElementById('submit-btn') .addEventListener('click', function(e) { e.preventDefault() captchaIns && captchaIns.verify() }) const request = NECaptchaValidate => { var xhr = new XMLHttpRequest() xhr.onreadystatechange = function() { console.log(this) if (this.readyState == 4) { if (this.status >= 200 && this.status < 300) { console.log('xhr.responseText', xhr.responseText) } } } xhr.open('post', 'http://192.168.1.227:20001/test163') xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ) xhr.send(JSON.stringify({ NECaptchaValidate })) } </script> </body> </html>
2. 后端代码
const Koa = require("koa"); const cors = require("koa2-cors"); const request = require("request"); const queryString = require("querystring"); const uuid = require("uuid"); const md5 = require("md5"); const app = new Koa(); // 写入自己申请的key id const secretKey = "XXXXXXXXXXXXXXXXXXXXX"; const captchaId = "XXXXXXXXXXXXXXXXXXXXX"; const secretId = "XXXXXXXXXXXXXXXXXXXXX"; const genSignature = (secretKey, paramsJson) => { const sorter = paramsJson => { const sortedJson = {}; const sortedKeys = Object.keys(paramsJson).sort(); for (let i = 0; i < sortedKeys.length; i++) { sortedJson[sortedKeys[i]] = paramsJson[sortedKeys[i]]; } return sortedJson; }; const sortedParam = sorter(paramsJson); let needSignatureStr = ""; for (let key in sortedParam) { var value = sortedParam[key]; needSignatureStr = needSignatureStr + key + value; } needSignatureStr += secretKey; return md5(needSignatureStr); }; app.use(cors()); app.use(async ctx => { if (ctx.request.path === "/test163") { let str = ""; const s = new Promise((resolve, reject) => { ctx.req.on("data", data => { str += data; }); ctx.req.on("end", () => { resolve(str); }); }); const data = JSON.parse(await s); const requestData = { captchaId, nonce: uuid().substr(4), // 32位 secretId, timestamp: new Date().getTime(), version: "v2", user: "", validate: data.NECaptchaValidate }; const signature = genSignature(secretKey, requestData); Object.assign(requestData, { signature }); const responseData = new Promise((resolve, reject) => { request( { headers: { "Content-Type": "application/x-www-form-urlencoded" }, url: "http://c.dun.163yun.com/api/v2/verify", body: queryString.stringify(requestData), method: "POST" }, (error, response, data) => { try { console.log('verify result: \n', data) resolve(data); } catch (e) { console.log("logout err", e); } } ); }); ctx.body = await responseData; } else { ctx.response.body = { code: 666 }; } }); app.listen(20001, () => { console.log("listen on: http://127.0.0.1:20001"); });