移动端微信连WiFi的实现流程如下。
1)用户手动选择SSID。
当用户打开手机WLAN设置的时候,会列出附近的WiFi信号列表,选择Portal路由器的SSID(这里为FreeWiFi),如图18-7所示。
图18-7 WiFi列表
2)手机浏览器弹出Portal页面并初始化。
在Portal页面中引用微信JS API,让原有WiFi Portal页面具备调起微信的能力。其代码如下。
<script type="text/javascript"> /** * 微信连WiFi协议3.1供运营商Portal调起微信浏览器使用 */ var loadIframe = null; var noResponse = null; var callUpTimestamp = 0; function putNoResponse(ev){ clearTimeout(noResponse); } function errorJump { var now = new Date.getTime; if((now - callUpTimestamp) > 4*1000){ return; } alert('该浏览器不支持自动跳转微信请手动打开微信/n如果已跳转请忽略此提示'); } myHandler = function(error) { errorJump; }; function createIframe{ var iframe = document.createElement("iframe"); iframe.style.cssText = "display:none;width:0px;height:0px;"; document.body.appendChild(iframe); loadIframe = iframe; } // 注册回调函数 function jsonpCallback(result){ if(result && result.success){ alert('WeChat will call up : ' + result.success + ' data:' + result.data); var ua=navigator.userAgent; if (ua.indexOf("iPhone") != -1 ||ua.indexOf("iPod")!=-1||ua.indexOf("iPad") != -1) { // iPhone document.location = result.data; }else{ if('false'=='true'){ alert('[强制]该浏览器不支持自动跳转微信请手动打开微信/n如果已跳转请忽 略此提示'); return; } createIframe; callUpTimestamp = new Date.getTime; loadIframe.src=result.data; noResponse = setTimeout(function{ errorJump; },3000); } }else if(result && !result.success){ alert(result.data); } } function Wechat_GotoRedirect(appId, extend, timestamp, sign, shopId, authUrl, mac, ssid, bssid){ // 将回调函数名称带到服务器端 var url = "https:// wifi.weixin.qq.com/operator/callWechatBrowser.xhtml?appId=" + appId + "&extend=" + extend + "×tamp=" + timestamp + "&sign=" + sign; // 如果sign后面的参数有值,则是新3.1发起的流程 if(authUrl && shopId){ url = "https:// wifi.weixin.qq.com/operator/callWechat.xhtml?appId=" + appId + "&extend=" + extend + "×tamp=" + timestamp + "&sign=" + sign + "&shopId=" + shopId + "&authUrl=" + encodeURIComponent(authUrl) + "&mac=" + mac + "&ssid=" + ssid + "&bssid=" + bssid; } alert(url); // 通过dom操作创建script节点,实现异步请求 var script = document.createElement('script'); script.setAttribute('src', url); document.getElementsByTagName('head')[0].appendChild(script); }</script>
Wechat_GotoRedirect函数参数的定义如表18-10所示。
表18-10 Wechat_GotoRedirect函数参数定义说明
Portal页面初始化时,需要同时向AC/AP请求移动端和AC/AP的MAC地址。请求代码如下。
// 获取手机MAC和路由器MAC的接口,由路由器厂家提供function getMac{ var objXMLHTTP = new XMLHttpRequest; var url = 'http:// fangbei.wifi/ubus'; objXMLHTTP.open('POST', url, true); objXMLHTTP.onreadystatechange = function{ if(objXMLHTTP.readyState == 4){ var str = objXMLHTTP.responseText ; alert(str); var items = JSON.parse(str).result[1]; mac = items.client_mac.replace(/(^/s*)|(/s*$)/g,''); apmac = items.macaddr.replace(/(^/s*)|(/s*$)/g,''); } } var data = '{"id":1234,"jsonrpc":"2.0","method":"call", "params":["000000000 00000000000000000000000", "mgmtd", "info", {}]}' ; objXMLHTTP.send(data);}
Portal页面放置一个按钮,提供用户一键连WiFi功能,如图18-8所示。
3)用户点击微信连WiFi按钮。
当用户点击微信连WiFi按钮时,浏览器需要请求AC/AP临时放行,并且调用JS API触发调起微信客户端。
调起微信的代码如下。
<script type="text/javascript"> var appId = "wx1b7559b818e3c33e"; var secretkey = "9cf2e6e5af383b068178d313270c237a"; var extend = "fangbei"; // 开发者自定义参数集合 var timestamp = new Date.getTime; // 时间戳(毫秒) var shop_id = "8191752"; // AP设备所在门店的ID var authUrl = "http:// www.fangbei.org/ auth.xhtml"; // 认证服务端URL var mac = "3c:91:57:c2:cc:af"; // 用户手机MAC地址安卓设备必需 var ssid = "A01-S001-R044"; // AP设备信号名称,非必需 var bssid = "00:a0:b1:4c:a1:c5"; // AP设备MAC地址,非必需 function callWechatBrowser{ var sign = hex_md5(appId + extend + timestamp + shop_id + authUrl + mac + ssid + bssid + secretkey); Wechat_GotoRedirect(appId, extend, timestamp, sign, shop_id, authUrl, mac, ssid, bssid); }</script>
上述代码中,签名的计算方法如下。
sign = MD5(appId + extend + timestamp + shop_id + authUrl + mac + ssid + bssid + secretkey);#注意这里timestamp是以毫秒为单位的当前时间戳
获得签名后,Portal将生成如下URL并发送到微信服务器。
https:// wifi.weixin.qq.com/operator/callWechat.xhtml?appId=wx1b7559b818e3c223&extend=fangbei×tamp=1450260747171&sign=c9847fdf18209a760891b8de653fa71c&shopId=8191751&authUrl=http%3A%2F%2Fwifi.weixin.qq.com%2Fassistant%2Fwifigw%2Fauth.xhtml%3FhttpCode%3D200&mac=3c:91:57:c5:cc:af&ssid=A01-S001-R04&bssid=00:e0:61:4c:a7:c5
4)微信服务器返回URL Scheme。
微信服务器将返回如下链接。
jsonpCallback({'success':true,'data':'weixin:// connectToFreeWifi/?apKey=http%3A%2F%2Fmp.weixin.qq.com%2Fmp%2Fwifi%3Fq%3D47b33c80e2910d51&ticket=ba21685ba44144dc988fa02ec8254053'})
其中,data数据解码如下。
weixin:// connectToFreeWifi/?apKey=http:// mp.weixin.qq.com/mp/wifi?q=47b33c80e2910d51&ticket=ba21685ba44144dc988fa02ec8254053
此处为一个URL Scheme。
weixin:// connectToFreeWifi/
5)调起微信连WiFi前置页面。
该URL Scheme将调起微信APP,并向微信服务器核对连WiFi注册信息及获取用户微信身份,微信服务器返回用户身份信息(OpenId、tid),微信打开微信连WiFi前置页面,如图18-9所示。
图18-8 Portal页
图18-9 微信连WiFi前置页
6)连接WiFi。
用户点击“立即连接”按钮,微信自动向authURL(JS API的传入参数)发起请求,提交认证所需的用户微信身份信息参数,包括extend、openId、tid。
http:// www.fangbei.org/auth.xhtml&extend=fangbei&openId=oiPuduCHIBb2aHvZoqSm1t7KbXtw&tid=010002d1eb4ee298934a7d44c1ece599ed57c4c010119bb23028b8
authURL参数说明如表18-11所示。
表18-11 authURL参数说明
7)云端auth URL返回AC认证结果。
authUrl所对应的后台认证服务器必须能识别这些参数信息,并向微信客户端返回AC认证结果,微信客户端将根据HTTP返回码,提示用户联网成功与否。
8)连接成功。
若HTTP返回码为200,则认为服务认证成功,微信客户端跳转到成功连接页,并默认显示关注公众号按钮,用户点击“完成”按钮后,将跳转到商家主页;若认证服务器需要转移认证请求,则返回302和下一跳地址,微信客户端将向下一跳地址再发起一次请求,302跳转仅支持一次;对于非200和302,或者超过次数的302返回码,视为认证失败,此次联网失败,微信客户端跳转到连接失败页。
WiFi连接成功页面如图18-10所示。
注意,微信客户端一次请求的等待时间为10s,请确保后台认证服务器在微信客户端向authUrl发送请求10s之内返回AC认证结果,即HTTP返回码。超过10s未返回认证结果将视为认证失败。
9)跳转商家主页。
点击“完成”,再跳转到默认模板或自定义商家主页链接,如图18-11所示。
图18-10 微信连WiFi成功页
图18-11 自定义链接页