映月读书网 > 微信公众平台开发:从零基础到ThinkPHP5高性能框架实践 > 18.3.3 Portal页面开发 >

18.3.3 Portal页面开发

移动端微信连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 + "&timestamp=" + timestamp + "&sign=" + sign;
        // 如果sign后面的参数有值,则是新3.1发起的流程
        if(authUrl && shopId){
            url = "https:// wifi.weixin.qq.com/operator/callWechat.xhtml?appId=" + appId + 
            "&extend=" + extend + "&timestamp=" + 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&timestamp=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 自定义链接页