当前位置: 首页 > article >正文

ESP8266+httpServer+GET+POST实现网页验证密码

1. 代码

#include "esp_http_server.h"
#include "esp_log.h"
#include "web_server.h"

// 辅助宏,用于计算两个数中的较小值
#define MIN(a, b) ((a) < (b) ? (a) : (b))

static const char *TAG = "wifi web_server";

const char login_page[] = {"\
<!DOCTYPE html>\
<html>\
<head>\
<meta charset='UTF-8'>\
<title>Sensor Configuration</title>\
</head>\
<body>\
<form method='POST' action='login.html'>\
<br>\
<P align=center style='color:#0066ff'><b>Sensor</b></P>\
<br><br>\
<P align=center>登录密码:&nbsp&nbsp&nbsp&nbsp;<input name=PASSWORD type=password size=18 maxlength=15></P>\
<br>\
<P align=center><input type=submit value='进入'></P>\
</form>\
</body>\
</html>\
"};

const char str_password_ok[] = "Password validated successfully";
const char str_password_ng[] = "Invalid password";
const char str_password_lost[] = "Missing PASSWORD field";

// HTTP服务器配置
esp_err_t http_get_handler(httpd_req_t *req)
{
//    const char* resp_str = "<html><body><h1>Hello ESP8266!</h1></body></html>";
    const char* resp_str = login_page;
    ESP_LOGI(TAG, "send login html");
    httpd_resp_send(req, resp_str, strlen(resp_str));
    return ESP_OK;
}

// 预期的密码
static const char *expected_password = "88888";

// 用于存储从请求体中读取的数据(注意:这里使用了固定大小)
#define REQUEST_BODY_MAX_SIZE 1024
static char request_body[REQUEST_BODY_MAX_SIZE] = {0};
static size_t request_body_len = 0;

// 辅助函数:从请求中读取数据(使用固定大小缓冲区)
static esp_err_t read_request_body(httpd_req_t *req) {
    //char buffer[128]; // 临时缓冲区,小于总缓冲区大小
    int len;

    // 循环读取请求体数据,直到没有更多数据可读或缓冲区满
    len = httpd_req_recv(req, request_body, REQUEST_BODY_MAX_SIZE - 1);
    if (len == HTTPD_SOCK_ERR_TIMEOUT) {
        // 超时错误处理
        ESP_LOGE("http_server", "Read timeout");
        return ESP_ERR_TIMEOUT;
    } else if (len < 0) {
        // 读取错误处理
        ESP_LOGE("http_server", "Error reading request body");
        return ESP_FAIL;
    }

    // 确保字符串以 null 结尾
    request_body[len] = '\0';
    request_body_len = len; // 更新请求体长度

    return ESP_OK;
}

esp_err_t http_post_handler(httpd_req_t *req) {
    // 重置请求体缓冲区
    memset(request_body, 0, REQUEST_BODY_MAX_SIZE);
    request_body_len = 0;

    // 读取整个请求体
    if (read_request_body(req) != ESP_OK) {
        // 读取请求体时发生错误
        httpd_resp_send_500(req);
        return ESP_FAIL;
    }

    // 假设请求体是 URL 编码的,并且包含 PASSWORD=...
    char *password_start = strstr(request_body, "PASSWORD=");
    if (password_start != NULL) {
        password_start += strlen("PASSWORD=");
        char *password_end = strchr(password_start, '&'); // 查找下一个字段的开始或字符串末尾
        if (password_end == NULL) {
            password_end = password_start + strlen(password_start); // 如果没有 '&',则指向末尾
        }

        // 计算密码长度(注意:这里要防止越界)
        size_t password_len = MIN(password_end - password_start, strlen(expected_password));

        // 比较密码
        if (strncmp(password_start, expected_password, password_len) == 0 &&
            (password_len == strlen(expected_password) || *(password_end - 1) == '&')) {
            httpd_resp_send(req, str_password_ok,strlen(str_password_ok));      //HTTP_OK
        } else {
            httpd_resp_send(req, str_password_ng,strlen(str_password_ng));  //HTTP_UNAUTHORIZED,
        }
    } else {
        httpd_resp_send(req, str_password_lost,strlen(str_password_lost));  //HTTP_BAD_REQUEST,
    }

    return ESP_OK;
}

httpd_handle_t start_webserver(void)
{
    httpd_handle_t server = NULL;
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();

    // GET 请求处理
    httpd_uri_t get_uri  = {
        .uri       = "/",
        .method    = HTTP_GET,
        .handler   = http_get_handler,
        .user_ctx  = NULL
    };

    // POST 请求处理(注意:这里假设表单提交到 /login)
    httpd_uri_t post_uri = {
        .uri       = "/login.html",
        .method    = HTTP_POST,
        .handler   = http_post_handler,
        .user_ctx  = NULL
    };

    // 启动HTTP服务器
    if (httpd_start(&server, &config) == ESP_OK) {
        ESP_LOGI(TAG, "Server started");
        if (httpd_register_uri_handler(server, &get_uri) != ESP_OK) {
            ESP_LOGE(TAG, "Failed to register GET URI handler");
        }
        if (httpd_register_uri_handler(server, &post_uri) != ESP_OK) {
            ESP_LOGE(TAG, "Failed to register POST URI handler");
        }
    } else {
        ESP_LOGE(TAG, "Failed to start server");
    }

    return server;
}

2 . 密码错误、正确的网页效果

在这里插入图片描述
在这里插入图片描述


http://www.kler.cn/news/310978.html

相关文章:

  • 承兑汇票识别API 银行承兑汇票识别接口 电子承兑汇票识别sdk 多进程识别
  • 鸿蒙Harmony应用开发,数据驾驶舱登录页面的实现
  • 使用python-pptx插入图片:将图片添加到幻灯片中并进行位置调整
  • 实战17-NavBar+Vip布局
  • 2024年9月python二级易错题和难题大全(附详细解析)(四)
  • Spring中存储Bean的常见注解
  • python的数据类型详解
  • MyBatis系统学习(三)——动态SQL
  • 简单题28-找出字符传中第一个匹配项的下标(Java and Python)20240918
  • ElasticSearch介绍+使用
  • 3. Python计算水仙花数
  • 利士策分享,赚钱与体重:一场关于生活平衡的微妙探索
  • 云计算服务的底层,虚拟化技术的实现原理
  • 假期学习--iOS 编译链接
  • 如何挑选一款性价比高的开放式耳机?高性价比宝藏蓝牙耳机推荐
  • 吸浮毛宠物空气净化器推荐,希喂、小米、有哈宠物空气净化器测评
  • 句子成分——每日一划(八)
  • 算法:30.串联所有单词的子串
  • 【MySQL】SQL语句的优化
  • Keil MDK5学习记录
  • 自定义Spring Security认证处理的完整解决方案
  • 2024ICPC第一场网络赛补题
  • 思通数科开源智能文档识别平台的核心功能
  • 在Linux服务器上如何实现自动化部署?
  • 【车载以太网】【SOME/IP】Wireshark 解析
  • Maven 的多种打jar包方式详细介绍、区别及使用教程——附使用命令
  • 分类预测|基于哈里斯鹰优化最小二乘支持向量机的数据分类预测Matlab程序HHO-LSSVM多特征输入多类别输出
  • 软件编程随想
  • 数据库MySQL、Mariadb、PostgreSQL、MangoDB、Memcached和Redis详细介绍
  • ARM64基础 -- 栈帧管理示例