使用ESP32C3开发板实现一个强制门户(Captive Portal)
开发板如上图所示,这本是LUATOS的开发板,但可惜我不会那一套工作链(虽然确实要简单一些),使用的还是IDF那一套。
强制门户是在授予新连接至Wi-Fi的用户更广的网络访问权限之前在其网页浏览器呈现中的网页,其常用于呈现可能需要认证或接受最终用户许可协议/可接受使用策略的着陆页或登录页。类似校园网的认证。
原理
终端设备在连接到WiFi之后,需要确定该WiFi是否能连接到互联网。厂商们的解决办法也很简单,就是向某个网址发起HTTP请求,如果能获得正确的数据,则证明这个WiFi能正常连接互联网。如果不行,则证明这个WiFi不能连接互联网。
比如苹果的设备会向
http://captive.apple.com/hotspot-detect.html
发送请求,直接打开会看到Success
的字样。
这个过程的具体原理是这样的:
在这里面我们有机会下手的就是DNS Server,让终端设备获得错误的服务器IP,进而使得终端设备发送HTTP请求到错误的网站(即我们的HTML)。这种做法通常被称为DNS拦截,一般的设备在检测到DNS拦截后,都会自动弹出发送HTTP请求后返回的页面(通常情况下的认证页面)。
实现
建立DNS Server
终端设备连接到ESP32的WiFi后,默认的DNS IP就是ESP32的内网IP(一般为192.168.4.1
)。
因此我们可以在ESP32上建立一个DNS Server,响应终端设备发起的DNS请求,并将所有的域名都解析到模块自己的IP上。
这样做的结果就是无论终端设备访问哪个域名来获取连通信息,都将被解析到ESP32自己。
例如,访问
http://captive.apple.com/hotspot-detect.html
会被拦截成http://192.168.4.1/hotspot-detect.html
。
建立HTTP Server
而当终端设备向ESP32发起HTTP请求后,捕获到的HTTP请求还需要做出相应的相应,才能让终端设备弹出网页。
因此我们还需要在ESP32上建立一个HTTP Server,响应终端设备发起的HTTP请求。
HTTP的底层协议是TCP,默认端口是80,所以我们只需要建立一个TCP服务器,监听80端口,收到请求后做出相应的回复。
代码实现
代码主要分为四部分,分别是:
main.c
- 初始化ESP32;dns_server
- DNS服务器;web_server
- TCP服务器;index.html
- 返回的网页。
项目地址:SIXiaolong1117/ESP32CaptivePortal: 可以用在ESP32上的强制门户。 (github.com)