用esp8266实现强制门户(连接WiFi自动打开网页)

1.首先你准备材料

一块Esb8266 NodeMCU CH340开发版(淘宝十几块钱买一个)一块0.96寸OLED 屏幕(4针)4根杜邦线电脑


这个是我用esp8266做的一个小时钟

2.有了材料后,再来了解一下强制门户认证的原理


强制门户认证所谓强制门户认证(Captive Portal),就是用户连接无线网之后并非直接获得互联网的连接权限,而是需要通过该无线网站点提供者所要求的身份验证之后才能得到访问互联网的许可(该许可由无线网站点提供者给予)。

你可以把无线站点想象成外卖平台,你要下单需要通过这个平台告知商家,由平台前往商家取货并负责订单的运输,你最后收到订单。那强制门户认证就是在你下单之前要求你进行登录平台以获得你相应的个人信息,订单记录等。

在很多公共场所都用到了这一技术,因为其方便快捷且易于管理,通常的无线加密诸如WPA2-WPA知道密码就能登录,难以管理连接的设备。在部分酒店,通过强制门户认证实现了输入房间号及姓名来接入互联网的认证方式,极大程度的提高了无线网接入客户的管理成本。在一些航班中,通过使用强制门户认证来实现对用户进行网络连接的定时收费。

我们在连接到wifi的时候,手机或者电脑都会访问一些特定的网址来检测这个wifi是不是有效wifi,还是一个无法访问互联网的wifi。而我们的突破口就在这个这些特定的网址

通过这个我手绘的图可以简单了解,现在我们只要将ip地址换成我们自己的ip地址就可以达到强制门户认证。

3.至于配置,可以参考这篇博客(1条消息) Esp8266时钟憨憨的憨憨的博客-CSDN博客esp8266时钟

4.在Arduino编写代码

#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // All Boards without Reset of the Display
const char* AP_NAME = "hello,world";//wifi名字
//暂时存储wifi账号密码
char sta_ssid[32] = "12345678";
char sta_password[64] = "12345678";
//配网页面代码
const char* page_html = "\
<!DOCTYPE html>\r\n\
<html lang='en'>\r\n\
<head>\r\n\
<meta charset='UTF-8'>\r\n\
<meta name='viewport' content='width=device-width, initial-scale=1.0'>\r\n\
<title>Document</title>\r\n\
</head>\r\n\
<body>\r\n\
<form name='input' action='/' method='POST'>\r\n\
      wifi名称: <br>\r\n\
      <input type='text' name='ssid'><br>\r\n\
      wifi密码:<br>\r\n\
      <input type='text' name='password'><br>\r\n\
      <input type='submit' value='保存'>\r\n\
  </form>\r\n\
</body>\r\n\
</html>\r\n\
";

const byte DNS_PORT = 53;//DNS端口号
IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP地址
DNSServer dnsServer;//创建dnsServer实例
ESP8266WebServer server(80);//创建WebServer

void handleRoot() {//访问主页回调函数
server.send(200, "text/html", page_html);
}

void handleRootPost() {//Post回调函数
Serial.println("handleRootPost");
if (server.hasArg("ssid")) {//判断是否有账号参数
  Serial.print("got ssid:");
  strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中
  Serial.println(sta_ssid);
    u8g2.setFont(u8g2_font_unifont_t_chinese2); // use chinese2 for all the glyphs of "你好世界"
  u8g2.setFontDirection(0);
  u8g2.clearBuffer();
  u8g2.setCursor(0, 15);
  u8g2.printf(sta_ssid);
  u8g2.sendBuffer();
  delay(1000);
} else {//没有参数
  Serial.println("error, not found ssid");
  server.send(200, "text/html", "<meta charset='UTF-8'>error, not found ssid");//返回错误页面
  return;
}
//密码与账号同理
if (server.hasArg("password")) {
  Serial.print("got password:");
  strcpy(sta_password, server.arg("password").c_str());
  Serial.println(sta_password);
    u8g2.setFont(u8g2_font_unifont_t_chinese2); // use chinese2 for all the glyphs of "你好世界"
u8g2.setFontDirection(0);
u8g2.clearBuffer();
u8g2.setCursor(0, 15);
u8g2.printf(sta_ssid);
u8g2.setCursor(0, 40);
u8g2.printf(sta_password);   // Chinese "Hello World"
u8g2.sendBuffer();
delay(1000);
} else {
  Serial.println("error, not found password");
  server.send(200, "text/html", "<meta charset='UTF-8'>error, not found password");
  return;
}

server.send(200, "text/html", "<meta charset='UTF-8'>保存成功");//返回保存成功页面
delay(2000);
//连接wifi
connectNewWifi();
}

void initBasic(void){//初始化基础
Serial.begin(115200);
WiFi.hostname("Smart-ESP8266");//设置ESP8266设备名
}

void initSoftAP(void){//初始化AP模式
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
if(WiFi.softAP(AP_NAME)){
  Serial.println("ESP8266 SoftAP is right");
}
}

void initWebServer(void){//初始化WebServer
//server.on("/",handleRoot);
//上面那行必须以下面这种格式去写否则无法强制门户
server.on("/", HTTP_GET, handleRoot);//设置主页回调函数
server.onNotFound(handleRoot);//设置无法响应的http请求的回调函数
server.on("/", HTTP_POST, handleRootPost);//设置Post请求回调函数
server.begin();//启动WebServer
Serial.println("WebServer started!");
}

void initDNS(void){//初始化DNS服务器
if(dnsServer.start(DNS_PORT, "*", apIP)){//判断将所有地址映射到esp8266的ip上是否成功
  Serial.println("start dnsserver success.");
}
else Serial.println("start dnsserver failed.");
}

void connectNewWifi(void){
int count = 0;
  while (1) {
  delay(500);
  count++;
  if(count > 1){//如果5秒内没有连上,就开启Web配网 可适当调整这个时间
    initSoftAP();
    initWebServer();
    initDNS();
    break;//跳出 防止无限初始化
  }
  Serial.print(".");
}
Serial.println("");
if(WiFi.status() == WL_CONNECTED){//如果连接上 就输出IP信息 防止未连接上break后会误输出
  Serial.println("WIFI Connected!");
   
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());//打印esp8266的IP地址
  server.stop();
}
}

void setup() {
initBasic();
initSoftAP();
initWebServer();
initDNS();
u8g2.begin();
u8g2.enableUTF8Print();   // enable UTF8 support for the Arduino print() function
 
}

void loop() {
server.handleClient();
dnsServer.processNextRequest();
 
}```

直接刷入你的esp8266就行,你输入的账号密码在保存后都可以在那个oled屏幕显示出来

5.如果要驱动和相关资源的话,可加qq群342096685

猜你喜欢

转载自blog.csdn.net/qq_59848320/article/details/120478659