基于ESP32的web网页输入2FA密码验证(TOTP方案)

文章介绍了如何使用ESP32开发板创建一个带有TOTP验证的Web服务器,用户可以通过网页输入验证码,ESP32接收并验证,实现WiFi配置和特定操作。
摘要由CSDN通过智能技术生成

 之前发过esp32 2FA密码生成(TOTP方案),这里分享一种通过网页提交totp code,esp32接收到该code后与当前的code比对,一致则执行某操作,不一致则执行另一操作的方案。

void handleConfigWifi() {
  //返回http状态
  //server.send(200, "text/html", SUCCESS_HTML);
  if (esp32_server.hasArg("totpkey")) {//判断是否有账号参数
    Serial.print("GOT TOTP KEY:");
    String totpkey = esp32_server.arg("totpkey");      //获取html表单输入框name名为"totpkey"的内容
    // strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中
    Serial.println(totpkey);
    if (totpCode == totpkey) {
      Serial.println("秘钥正确");
      esp32_server.send(200, "text/plain", "TOTP CODE RIGHT");//向浏览器返回结果正确

      //在这里添加秘钥正确后执行的操作

    }
    else {
      Serial.println("秘钥错误");
      esp32_server.send(200, "text/plain", "TOTP CODE ERROR");//向浏览器返回结果错误

      //在这里添加秘钥错误后执行的操作
    }
  } else { //没有参数
    Serial.println("error,not fund TOTP CODE");
    esp32_server.send(200, "text/html", "<meta charset='UTF-8'>error,error,not fund TOTP CODE");//返回错误页面
    return;
  }
}

该代码为对输入秘钥的比对功能,全部代码见文末。

实现了以下功能:

1:esp32 AP与STA共存,连接wifi的同时打开AP,可通过两种方案访问网页。

2:totp code的生成。

3:建立web服务器,由网页输入totp code,点击按钮提交。

4:esp32接收到网页发过来的code,与自己生成的对比,执行相关操作,并向网页返回相关结果。

可以自行添加例如打开继电器,关闭继电器,向某个服务器发送消息等功能。

图一输入界面

图二正确界面

图三错误界面

完整代码如下:

#include<WiFi.h>
#include<WebServer.h>
#include <NTPClient.h>
#include <TOTP.h>
WebServer  esp32_server(80);  //声明一个 WebServer 的对象,对象的名称为 esp32_server
//设置网络服务器响应HTTP请求的端口号为 80
//定义根目录首页网页HTML源代码
#define ROOT_HTML  "<!DOCTYPE html><html><head><title></title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><style type=\"text/css\">.input{display: block; margin-top: 10px;}.input span{width: 100px; float: left; float: left; height: 36px; line-height: 36px;}.input input{height: 30px;width: 200px;}.btn{width: 120px; height: 35px; background-color: #000000; border:0px; color:#ffffff; margin-top:15px; margin-left:100px;}</style><body><form method=\"POST\" action=\"TOTP\"><label class=\"input\"><span>TOTP KEY</span><input type=\"text\" name=\"totpkey\" value=\"\"></label><input class=\"btn\" type=\"submit\" name=\"submit\" value=\"Submie\"> <p><span></form>"

//设置wifi
const char *AP_SSID = "test";
const char *AP_Password = "";//ap的ssid和密码,这里设置空则为无密码

char ssid[] = "ssid";
char password[] = "password"; //要连接的ssid和密码


uint8_t hmacKey[] = {0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x6b, 0x65, 0x79, 0x30};

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
TOTP totp = TOTP(hmacKey, 10);
String totpCode = String("");

void handleRoot()  //该函数内为处理网站根目录 “/” 时所执行的内容
{
  Serial.print("客户端访问!");
  esp32_server.send(200, "text/html", ROOT_HTML  "</body></html>");
}
void handleFound()
{
  esp32_server.send(200, "text/html", ROOT_HTML  "</body></html>");
}


void handleConfigWifi() {
  //返回http状态
  //server.send(200, "text/html", SUCCESS_HTML);
  if (esp32_server.hasArg("totpkey")) {//判断是否有账号参数
    Serial.print("GOT TOTP KEY:");
    String totpkey = esp32_server.arg("totpkey");      //获取html表单输入框name名为"ssid"的内容
    // strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中
    Serial.println(totpkey);
    if (totpCode == totpkey) {
      Serial.println("秘钥正确");
      esp32_server.send(200, "text/plain", "TOTP CODE RIGHT");//向浏览器返回结果正确

      //在这里添加秘钥正确后执行的操作

    }
    else {
      Serial.println("秘钥错误");
      esp32_server.send(200, "text/plain", "TOTP CODE ERROR");//向浏览器返回结果错误

      //在这里添加秘钥错误后执行的操作
    }
  } else { //没有参数
    Serial.println("error, not found ssid");
    esp32_server.send(200, "text/html", "<meta charset='UTF-8'>error, not found ssid");//返回错误页面
    return;
  }
}


// 设置处理404情况的函数'handleNotFound'
void handleNotFound() {           // 当浏览器请求的网络资源无法在服务器找到时通过此自定义函数处理
  handleRoot();                 //访问不存在目录则返回配置页面
  //   server.send(404, "text/plain", "404: Not found");
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);  //初始化串口通信并设置波特率为115200
  WiFi.mode(WIFI_AP_STA);//设置ap和sta共存模式
  WiFi.softAP(AP_SSID, AP_Password); //设置AP模式热点的名称和密码,密码可不填则发出的热点为无密码热点

  Serial.print("\n ESP32建立的wifi名称为:");
  Serial.print(AP_SSID);  //串口输出ESP32建立的wifi的名称
  Serial.print("\nESP32建立wifi的IP地址为:");
  Serial.print(WiFi.softAPIP());  //串口输出热点的IP地址
  WiFi.begin(ssid, password);//连接2wifi
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Establishing connection to WiFi...");
  }
  Serial.print("Connected to WiFi with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  esp32_server.on("/", HTTP_GET, handleRoot);                      //  当浏览器请求服务器根目录(网站首页)时调用自定义函数handleRoot处理,设置主页回调函数,必须添加第二个参数HTTP_GET,否则无法强制门户
  esp32_server.on("/TOTP", HTTP_POST, handleConfigWifi);     //  当浏览器请求服务器/configwifi(表单字段)目录时调用自定义函数handleConfigWifi处理
  esp32_server.onNotFound(handleNotFound);                         //当浏览器请求的网络资源无法在服务器找到时调用自定义函数handleNotFound处理
  //Tells the server to begin listening for incoming connections.Returns None
  esp32_server.begin();   //启动WEB SERVER
  timeClient.begin();
}
void loop() {
  // put your main code here, to run repeatedly:
  esp32_server.handleClient();
  timeClient.update();

  // 生成 TOTP 代码,如果与前一个代码不同,则串口输出
  String newCode = String(totp.getCode(timeClient.getEpochTime()));
  if (totpCode != newCode) {
    totpCode = String(newCode);
    Serial.print("TOTP code: ");
    Serial.println(newCode);//串口输出totpcode,可以删除
  }
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值