新版微信提供了微信连WiFi功能。现在,通过微信可以实现下图这种更便捷的微信WiFi认证方式。
开发者可以利用微信公众平台的Wi-Fi硬件鉴权协议接口和Wiwiz系统的相关开发接口,轻松地实现上述认证方式。
步骤如下:
1.在微信公众平台中创建门店,开通微信连WiFi权限,并添加设备。设置SSID,并获取shopId、appId、secretKey。注意:添加设备时“设备类型”应选为“portal型设备”,“接入方式”选为“设备改造后接入”,如下图。
2.在Wiwiz Web面板中设置热点,将认证方式设为“电子招待券”,并添加一个电子招待券“1min”,并设置使用时长为1分钟。如下图。
3. 将认证页面类型设置为“自定义认证页面HTML”,将AuthPage.htm的源码复制到认证页面设置的“自定义HTML”项目中。
4. 将认证后页面类型设置为“自定义HTML”,将PostAuth.htm的源码复制到认证后页面设置的“自定义HTML”项目中。
5. 将WeixinListener.jsp保存与Web服务器(须支持JSP)。
注意事项:
1.PostAuth.htm和WeixinListener.jsp源码中的部分参数请按源码中的说明做替换处理。
2. v6.2.5以前的微信版本对该认证方式可能会有问题。
以下是本案例的源码:
AuthPage.htm
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Language" content="zh"> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title> 微信连WiFi </title> <!-- 必须引入AuthPageScript.js --> <script src="http://cp.wiwiz.com/as/AuthPageScript.js"></script> <script> /* 回调函数。“获取验证码”按钮按下后,将自动调用此函数。可根据code值自行改写该函数。 */ function WiwizSmsVerifyMsg(code) { if (code == "-1") { alert("手机号码不可为空!"); } else if(code == "0") { alert("验证码已通过短信发送至您的手机,请注意查收。然后请在认证页面输入验证码。"); } else if(code == "1") { alert("该热点不允许进行手机号码验证。如有疑问请您联系热点管理员。"); } else if(code == "2") { alert("该热点不允许进行手机号码验证。如有疑问请您联系热点管理员。"); } else if(code == "3") { alert("该手机号码不允许进行验证。如有疑问请您联系热点管理员。"); } else if(code == "4") { alert("手机号码验证过于频繁,请稍后再试。"); } else if(code == "5") { alert("该手机号码进行验证次数已超过今日上限。"); } else if(code == "6") { alert("热点认证服务已暂停,不可进行手机验证。"); } else if(code == "7") { alert("该热点手机验证次数已超过配额。请联系热点管理员。"); } else if(code == "8") { alert("请求已超时,请刷新认证页面。"); } else if(code == "9") { alert("请使用上一次通过短信接收到的验证码。"); } else if(code == "99") { alert("验证短信发送失败。请检查手机号码的有效性,或联系热点管理员。"); } else if(code == "999") { alert("系统异常,验证短信发送失败。请联系热点管理员。"); } else { alert("系统异常。请联系热点管理员。"); } } /* 回调函数。“认证”按钮按下后,如报错将自动调用此函数。可根据code值自行改写该函数。 */ function WiwizAuthPageError(code) { if (code == 1) { alert("您无法使用此网络,除非您认同此协议条款。"); } else if(code == 2) { alert("请输入用户名。"); } else if(code == 3) { alert("用户名或密码错误。"); } else if(code == 4) { alert("电子招待券无效。"); } else if(code == 5) { alert("超过该电子招待券的最大使用人数限制。"); } else if(code == 6) { alert("超过最大在线用户数。"); } else if(code == 7) { alert("请输入手机号码。"); } else if(code == 8) { alert("热点已停用。"); } else if(code == 32) { alert("账户存在异常,暂时锁定中。"); } else if(code == 35) { alert("手机验证码错误或已超时。"); } else if(code == 36) { alert("该手机号码不允许进行验证。如有疑问请您联系热点管理员。"); } else if(code == 37) { alert("该手机号码进行验证次数已超过今日上限。"); } else { alert("未知错误。错误码:"+ code); } } /* 认证完成前先调用此函数 */ function WiwizBeforeAuthDone() { } </script> </head> <body> <form name="myform" id="myform" action="" method="post"> <!-- 设置时长为1分钟的电子招待券 --> <input name="voucher" id="voucher" type="hidden" value="1min" /> <center> <br> 微信连WiFi 认证页面示例 <br><br><br> <!-- 用于开始触发认证的按钮,onclick事件必须调用WiwizStartAuth()函数 --> <input type="button" name="login" value=" 微信连WiFi " onclick="WiwizStartAuth();" /> </center> </form> </body></html> |
PostAuth.htm
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Language" content="zh"> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title> 正在打开微信 </title> <!--MD5算法--> <script> var hexcase=0;var b64pad="";var chrsz=8;function hex_md5(s){return binl2hex(core_md5(str2binl(s),s.length*chrsz))}function b64_md5(s){return binl2b64(core_md5(str2binl(s),s.length*chrsz))}function str_md5(s){return binl2str(core_md5(str2binl(s),s.length*chrsz))}function hex_hmac_md5(key,data){return binl2hex(core_hmac_md5(key,data))}function b64_hmac_md5(key,data){return binl2b64(core_hmac_md5(key,data))}function str_hmac_md5(key,data){return binl2str(core_hmac_md5(key,data))}function md5_vm_test(){return hex_md5("abc")=="900150983cd24fb0d6963f7d28e17f72"}function core_md5(x,len){x[len>>5]|=0x80<<((len)%32);x[(((len+64)>>>9)<<4)+14]=len;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;for(var i=0;i<x.length;i+=16){var olda=a;var oldb=b;var oldc=c;var oldd=d;a=md5_ff(a,b,c,d,x[i+0],7,-680876936);d=md5_ff(d,a,b,c,x[i+1],12,-389564586);c=md5_ff(c,d,a,b,x[i+2],17,606105819);b=md5_ff(b,c,d,a,x[i+3],22,-1044525330);a=md5_ff(a,b,c,d,x[i+4],7,-176418897);d=md5_ff(d,a,b,c,x[i+5],12,1200080426);c=md5_ff(c,d,a,b,x[i+6],17,-1473231341);b=md5_ff(b,c,d,a,x[i+7],22,-45705983);a=md5_ff(a,b,c,d,x[i+8],7,1770035416);d=md5_ff(d,a,b,c,x[i+9],12,-1958414417);c=md5_ff(c,d,a,b,x[i+10],17,-42063);b=md5_ff(b,c,d,a,x[i+11],22,-1990404162);a=md5_ff(a,b,c,d,x[i+12],7,1804603682);d=md5_ff(d,a,b,c,x[i+13],12,-40341101);c=md5_ff(c,d,a,b,x[i+14],17,-1502002290);b=md5_ff(b,c,d,a,x[i+15],22,1236535329);a=md5_gg(a,b,c,d,x[i+1],5,-165796510);d=md5_gg(d,a,b,c,x[i+6],9,-1069501632);c=md5_gg(c,d,a,b,x[i+11],14,643717713);b=md5_gg(b,c,d,a,x[i+0],20,-373897302);a=md5_gg(a,b,c,d,x[i+5],5,-701558691);d=md5_gg(d,a,b,c,x[i+10],9,38016083);c=md5_gg(c,d,a,b,x[i+15],14,-660478335);b=md5_gg(b,c,d,a,x[i+4],20,-405537848);a=md5_gg(a,b,c,d,x[i+9],5,568446438);d=md5_gg(d,a,b,c,x[i+14],9,-1019803690);c=md5_gg(c,d,a,b,x[i+3],14,-187363961);b=md5_gg(b,c,d,a,x[i+8],20,1163531501);a=md5_gg(a,b,c,d,x[i+13],5,-1444681467);d=md5_gg(d,a,b,c,x[i+2],9,-51403784);c=md5_gg(c,d,a,b,x[i+7],14,1735328473);b=md5_gg(b,c,d,a,x[i+12],20,-1926607734);a=md5_hh(a,b,c,d,x[i+5],4,-378558);d=md5_hh(d,a,b,c,x[i+8],11,-2022574463);c=md5_hh(c,d,a,b,x[i+11],16,1839030562);b=md5_hh(b,c,d,a,x[i+14],23,-35309556);a=md5_hh(a,b,c,d,x[i+1],4,-1530992060);d=md5_hh(d,a,b,c,x[i+4],11,1272893353);c=md5_hh(c,d,a,b,x[i+7],16,-155497632);b=md5_hh(b,c,d,a,x[i+10],23,-1094730640);a=md5_hh(a,b,c,d,x[i+13],4,681279174);d=md5_hh(d,a,b,c,x[i+0],11,-358537222);c=md5_hh(c,d,a,b,x[i+3],16,-722521979);b=md5_hh(b,c,d,a,x[i+6],23,76029189);a=md5_hh(a,b,c,d,x[i+9],4,-640364487);d=md5_hh(d,a,b,c,x[i+12],11,-421815835);c=md5_hh(c,d,a,b,x[i+15],16,530742520);b=md5_hh(b,c,d,a,x[i+2],23,-995338651);a=md5_ii(a,b,c,d,x[i+0],6,-198630844);d=md5_ii(d,a,b,c,x[i+7],10,1126891415);c=md5_ii(c,d,a,b,x[i+14],15,-1416354905);b=md5_ii(b,c,d,a,x[i+5],21,-57434055);a=md5_ii(a,b,c,d,x[i+12],6,1700485571);d=md5_ii(d,a,b,c,x[i+3],10,-1894986606);c=md5_ii(c,d,a,b,x[i+10],15,-1051523);b=md5_ii(b,c,d,a,x[i+1],21,-2054922799);a=md5_ii(a,b,c,d,x[i+8],6,1873313359);d=md5_ii(d,a,b,c,x[i+15],10,-30611744);c=md5_ii(c,d,a,b,x[i+6],15,-1560198380);b=md5_ii(b,c,d,a,x[i+13],21,1309151649);a=md5_ii(a,b,c,d,x[i+4],6,-145523070);d=md5_ii(d,a,b,c,x[i+11],10,-1120210379);c=md5_ii(c,d,a,b,x[i+2],15,718787259);b=md5_ii(b,c,d,a,x[i+9],21,-343485551);a=safe_add(a,olda);b=safe_add(b,oldb);c=safe_add(c,oldc);d=safe_add(d,oldd)}return Array(a,b,c,d)}function md5_cmn(q,a,b,x,s,t){return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b)}function md5_ff(a,b,c,d,x,s,t){return md5_cmn((b&c)|((~b)&d),a,b,x,s,t)}function md5_gg(a,b,c,d,x,s,t){return md5_cmn((b&d)|(c&(~d)),a,b,x,s,t)}function md5_hh(a,b,c,d,x,s,t){return md5_cmn(b^c^d,a,b,x,s,t)}function md5_ii(a,b,c,d,x,s,t){return md5_cmn(c^(b|(~d)),a,b,x,s,t)}function core_hmac_md5(key,data){var bkey=str2binl(key);if(bkey.length>16)bkey=core_md5(bkey,key.length*chrsz);var ipad=Array(16),opad=Array(16);for(var i=0;i<16;i++){ipad[i]=bkey[i]^0x36363636;opad[i]=bkey[i]^0x5C5C5C5C}var hash=core_md5(ipad.concat(str2binl(data)),512+data.length*chrsz);return core_md5(opad.concat(hash),512+128)}function safe_add(x,y){var lsw=(x&0xFFFF)+(y&0xFFFF);var msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&0xFFFF)}function bit_rol(num,cnt){return(num<<cnt)|(num>>>(32-cnt))}function str2binl(str){var bin=Array();var mask=(1<<chrsz)-1;for(var i=0;i<str.length*chrsz;i+=chrsz)bin[i>>5]|=(str.charCodeAt(i/chrsz)&mask)<<(i%32);return bin}function binl2str(bin){var str="";var mask=(1<<chrsz)-1;for(var i=0;i<bin.length*32;i+=chrsz)str+=String.fromCharCode((bin[i>>5]>>>(i%32))&mask);return str}function binl2hex(binarray){var hex_tab=hexcase?"0123456789ABCDEF":"0123456789abcdef";var str="";for(var i=0;i<binarray.length*4;i++){str+=hex_tab.charAt((binarray[i>>2]>>((i%4)*8+4))&0xF)+hex_tab.charAt((binarray[i>>2]>>((i%4)*8))&0xF)}return str}function binl2b64(binarray){var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var str="";for(var i=0;i<binarray.length*4;i+=3){var triplet=(((binarray[i>>2]>>8*(i%4))&0xFF)<<16)|(((binarray[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((binarray[i+2>>2]>>8*((i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>binarray.length*32)str+=b64pad;else str+=tab.charAt((triplet>>6*(3-j))&0x3F)}}return str} </script> <!--微信组件--> <script type="text/javascript" src="https://wifi.weixin.qq.com/resources/js/wechatticket/wechatutil.js" ></script> <script> /* 获取URL参数值 */ function getUrlParameter(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i"); var r = window.location.search.substr(1).match(reg); if (r!=null) return decodeURIComponent(r[2]); return null; } /* 呼起微信 */ function doWeRedirect(){ //在微信公众平台,创建门店并启用微信连WiFi权限后,可获取以下四个参数。 var appId = 'wx310eea55b32cbec5'; var ssid = 'Wiwiz'; var shop_id = '7361374'; var secretkey = '125281cf148fd9c776e4e963df2d9489'; var extend = getUrlParameter("t"); //Wiwiz传入的tokencode var mac = getUrlParameter("mac"); //Wiwiz传入的终端MAC地址 var authUrl = 'http://192.168.2.110/as/test/wxtest/WeixinListener.jsp'; //请替换为你的服务器实际地址 var timeStamp = new Date().getTime(); var sign= hex_md5(appId + extend + timeStamp + shop_id + authUrl + mac + ssid + secretkey); Wechat_GotoRedirect( appId , extend , timeStamp, sign, shop_id, authUrl, mac, ssid, '' ); } </script> </head> <body onload="doWeRedirect();"> <center> <br> 正在打开微信,请稍候... </center> </body> </html> |
WeixinListener.jsp
<%@ page import="java.io.*"%><%@ page import="java.util.*"%><%@ page import="java.text.*"%><%@ page import="java.net.*"%><%! /* 获取当前时间 */ public static String getTime() { Calendar c = Calendar.getInstance(); Date dt = c.getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(dt); } /* 时间加减 */ public static String addTime(String time, int field, int amount) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dCurEndTime = sdf.parse(time); Calendar c = Calendar.getInstance(); c.setTime(dCurEndTime); c.add(field, amount); Date dt = c.getTime(); return sdf.format(dt); } %><% String extend = request.getParameter("extend"); //调用呼起微信JSAPI时传递的extend参数(Wiwiz传入的tokencode) String openId = request.getParameter("openId"); //用户的微信openId String tid = request.getParameter("tid"); //为加密后的用户手机号码(仅作网监部门备案使用) String userkey = "XXXXXXXXXXXXXXX"; //Wiwiz平台的User Key(!!!注意:请替换为用户的实际值!!!) //------- Debug -------- System.out.println("[WeixinListener.jsp] extend = "+ extend); System.out.println("[WeixinListener.jsp] openId = "+ openId); System.out.println("[WeixinListener.jsp] tid = "+ tid); //---------------------- if(extend != null) { //String set_endtime=URLEncoder.encode("", "UTF-8"); //不限上网时长 String set_endtime=URLEncoder.encode(addTime(getTime(), Calendar.MINUTE, 5), "UTF-8"); //允许上网5分钟 //调用Wiwiz Auth API的“认证连接的断开时间动态设置接口” URL url = new URL("http://cp.wiwiz.com/as/s/login2/?set_endtime="+ set_endtime +"&t="+ extend +"&userkey="+ userkey); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); httpConn.connect(); BufferedReader in = new BufferedReader( new InputStreamReader(httpConn.getInputStream(), "UTF-8")); String responseStr = ""; String line; while ((line = in.readLine()) != null) { responseStr += line; } in.close(); httpConn.disconnect(); //------- Debug -------- System.out.println("[WeixinListener.jsp] responseStr = "+ responseStr); //---------------------- if(responseStr.startsWith("ERR")) { //如遇到错误则返回HTTP403,使告知微信连接失败。 response.setStatus(403); } else { //如成功,则返回HTTP200,使告知微信连接成功。 response.setStatus(200); } } %> |