[转载]为你的App增加WIFI认证检测,让用户体验更加丝滑

[转载]为你的App增加WIFI认证检测,让用户体验更加丝滑

前言

前段时间在上海坐地铁时连接了花生地铁WIFI,打开QQ音乐开始听歌,QQ音乐居然给了我一个"WIFI认证提醒"的弹窗,点击认证就跳转到了花生地铁WIFI的认证页,之后顺利联网成功,体验非常爽。作为一名iOS开发,不禁思考这个是怎么做到的呢?忘记WIFI重新连接后,打开手机里各个应用轮番测试一遍,发现QQ音乐、QQ、QQ空间三个应用都做了比较好的WIFI认证提示:

成功提示.png

而其它的大应用如微信、手淘、支付宝、钉钉、美团、点评、爱奇艺、百度地图等则都没有给出认证提醒,而是提示我检查网络设置等,说明许多App都没重视到这个细节,而其实现在这种场景还是很多的,比如花生地铁WIFI、i-Shanghai、i-hangzhou、alibaba-guest和其它许多公共场所的WIFI,还是有必要做一个优化~

失败提示.png

关于Captive Portal

经过一番调研,这种需认证才能使用的WIFI,使用的是Captive Portal机制,中文通常译作“强制主页”或“强制登录门户”,一个Captive Portal是一个Web登录页面,通常由网络运营商或网关在用户能够正常访问互联网之前拦截用户的请求并将一个强制登录或认证主页呈现(通常是通过浏览器)给用户。该页面可能要求用户输入认证信息、支付、接受某些条款或者其他用户授权等,随后用户才能被授权访问互联网。该技术广泛用于移动和个人宽带服务,包括有线电视、商业WiFi、家庭热点等,也可用于访问企业和住宅区有线网络。详细可参看wiki:https://en.wikipedia.org/wiki/Captive_portal

大多数需认证WIFI实现Captive Portal是通过HTTP重定向的方式,也有一些是通过DNS劫持或ICMP重定向的方式。

如何检测Captive Portal

iOS和Android系统其实早就实现了Captive Portal的检测机制,只是有一些WIFI会绕过这样机制。就需要我们额外再做一次检测了。

详细可参看:
关于Apple的Captive Network Assistant
Bypasses Apple Captive Network Assistant Login in iOS 7

根据Captive Portal的实现方式和特点,我们有以下两种常用检测方法:( 欢迎补充~ )

1. 判断网页的host是否完全变了

由于连接了需认证WIFI后,通过浏览器访问任何网页都会得到Captive Portal页面,所以对于iOS应用,一个比较简单的检测方法是用WKWebView加载某一个网页,在decidePolicyForNavigationAction代理方法里,拿到navigationAction.request.URL看host是不是完全变了,如果完全变了即可判断当前WIFI需要认证。

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    decisionHandler(WKNavigationActionPolicyAllow);
    
    self.trueUrl = navigationAction.request.URL;
    if (self.openTestMode) {
        // 测试用 这个url是上海花生地铁wifi的认证页,连上上海花生地铁wifi后,未认证时访问所有网页都会被重定向到该地址
        self.trueUrl= [NSURL URLWithString:@"http://portal.wifi8.com/wifiapp"];
    }
    if ([self.trueUrl.host containsString:@"baidu.com"]) {
        if (_networkCheckComplection) {
            _networkCheckComplection(NO);
            _networkCheckComplection = nil;
        }
    } else { // 网页被重定向到了self.trueUrl,wifi需要认证
        if (_networkCheckComplection) {
            _networkCheckComplection(YES);
            _networkCheckComplection = nil;
        }
        
        if (_needAlert) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"WI-FI认证提醒" message:@"检测到当前WI-FI需要认证才能使用,请尝试去认证网络" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"认证", nil];
            [alert show];
            _needAlert = NO;
        }
    }
}

Android端的检测也可以采用这样的方式,具体可参看google的文档:https://developer.android.com/reference/java/net/HttpURLConnection.html ,其中提到的判断机制如下:

图片.png

有一点需要注意的是,判断host完全相等不是特别合适,比如在WKWebView里访问http://www.baidu.com ,可能会被重定向到http://m.baidu.com ,这样则不属于WIFI需要认证的情况。

2. 访问特定网页,判断HTTP状态码

也可以通过判断HTTP状态码的方式来检测Captive Portal。比如访问google提供的一个空白网页http://clients1.google.com/generate_204 ,如果返回的HTTP状态码是204,则可判断当前网络无需认证,否则需要提醒用户认证网络。

详细可参看:
关于Android的captive portal

检测Captive Portal的iOS版Demo

基于判断host的方式,我写了一个检测Captive Portal的小Demo放在了github,其中用于Captive Portal检测的工具类是CaptivePortalCheck,没有任何外部依赖,即拿即用,欢迎尝试~

文中内容如有不对,欢迎指正~

粘贴图片3.png

小礼物走一走,来简书关注我

 
日记本
 

Web note ad 1

 
KFC是做基的
10楼 · 2019.01.28 11:50

iOS11下,SFSafariViewController有些问题,页面会白屏...原因暂时未知,如果你知道求告知~
这个问题解决方法: 你可以加一个延时 dispatch_after 个 0.5秒 在进行 SFSafariViewController 初始化跳转,但具体原因不清楚

 
 
青阳的桌边谈资儿
9楼 · 2018.11.21 04:12

我想自己建立一个 WIFI 强制主页站点应该怎么做?不需要认证的,只需要用户连接WIFI后弹出即可。

 
感谢
2018.11.21 04:12 回复
 
@青阳的桌边谈资儿 这个没了解过哈。
2018.11.21 10:59 回复
 
 
Dwyane_Coding
8楼 · 2018.09.16 21:58

源于生活:clap:

1人赞 回复
 
 
进击的小巨牛
7楼 · 2018.04.28 17:28

想问下如何加到项目中,当有需认证WiFi的时候弹出来去认证?

 
把CaptivePortalCheck拖到项目里,在合适的时机调CaptivePortalCheck的checkIsWifiNeedAuthPasswordWithComplection方法,比如应用启动和网络状态变化时,调的时候判断下当前网络是WIFI
2018.05.01 01:49 回复
 
 
kaijiemu
6楼 · 2018.01.22 15:04

用了demo 判断无效,一直是返回百度。。。能怎么联系你请教下吗?

 
@kaijiemu 你目前连接的WIFI,是需要认证的吗?
2018.01.22 15:11 回复
 
@半尺尘 找到问题了,不要请求百度,请求苹果提供的网址:http://captive.apple.com/hotspotdetect.html 就可以!
2018.01.22 16:00 回复
 
@kaijiemu:+1:
2018.01.22 16:02 回复
 
 
__阳阳
5楼 · 2017.10.24 21:14

最近要用到, mark了

 
 
ocarol
4楼 · 2017.10.18 18:51

这个细节不错,棒棒哒

1人赞 回复
 
 
zhouyangyng
3楼 · 2017.09.26 17:25

不错啊:blush:

 
 
Jonny_Li
2楼 · 2017.09.22 15:49

这个不错

1人赞 回复
 

 

posted @ 2019-03-22 17:02  yuhui.Mr  阅读(473)  评论(0)    收藏  举报