注册登陆(最新版)

news2024/11/24 11:40:52

整体概述

本项目中,使用数据库连接池实现服务器访问数据库的功能,使用POST请求完成注册和登录的校验工作。

本文内容

本篇将介绍同步实现注册登录功能,具体的涉及到流程图,载入数据库表,提取用户名和密码,注册登录流程与页面跳转的的代码实现。

流程图,描述服务器从报文中提取出用户名密码,并完成注册和登录校验后,实现页面跳转的逻辑。

载入数据库表,结合代码将数据库中的数据载入到服务器中。

提取用户名和密码,结合代码对报文进行解析,提取用户名和密码。

注册登录流程,结合代码对描述服务器进行注册和登录校验的流程。

页面跳转,结合代码对页面跳转机制进行详解。

流程图

具体的,描述了GET和POST请求下的页面跳转流程。

载入数据库表

将数据库中的用户名和密码载入到服务器的map中来,map中的key为用户名,value为密码。

/**
 * 初始化MySQL查询结果
 * 
 * 该函数用于从数据库中查询用户信息,并将结果存储在一个map中
 * 使用了RAII技术管理数据库连接,确保异常情况下能正确释放资源
 * 
 * 参数:
 * connPool: 数据库连接池的指针,用于获取数据库连接
 */
void http_conn::initmysql_result(connection_pool* connPool) {
    // 声明MySQL连接指针,初始化为nullptr
    MYSQL *mysql = nullptr;
    // 使用RAII技术管理MySQL连接,确保异常安全
    connectionRAII mysqlcon(&mysql, connPool);

    // 执行SQL查询语句,选择user表中的username和passwd字段
    // 如果查询失败,记录错误日志
    if (mysql_query(mysql, "SELECT username, passwd from user")) {
        LOG_ERROR("SELECT error: %s\n", mysql_error(mysql));
    }

    // 获取查询结果集
    MYSQL_RES* result = mysql_store_result(mysql);
    // 获取结果集的列数
    int num_fields = mysql_num_fields(result);
    // 获取结果集的所有字段结构数组
    MYSQL_FIELD *field = mysql_fetch_fields(result);
    // 遍历结果集,将每行的用户名和密码添加到users map中
    while (MYSQL_ROW row = mysql_fetch_row(result)) {
        string temp1(row[0]);
        string temp2(row[1]);
        users[temp1] = temp2;
    }
}
提取用户名和密码

服务器端解析浏览器的请求报文,当解析为POST请求时,cgi标志位设置为1,并将请求报文的消息体赋值给m_string,进而提取出用户名和密码。

同步线程登录注册

通过m_url定位/所在位置,根据/后的第一个字符判断是登录还是注册校验。

  • 2
    • 登录校验
  • 3
    • 注册校验

根据校验结果,跳转对应页面。另外,对数据库进行操作时,需要通过锁来同步。

页面跳转

通过m_url定位/所在位置,根据/后的第一个字符,使用分支语句实现页面跳转。具体的,

  • 0
    • 跳转注册页面,GET
  • 1
    • 跳转登录页面,GET
  • 5
    • 显示图片页面,POST
  • 6
    • 显示视频页面,POST
  • 7
    • 显示关注页面,POST
/**
 * 解析HTTP请求的主体内容
 * 
 * @param text 指向读取到的请求主体内容的指针
 * @return 返回解析后的请求状态
 */
http_conn::HTTP_CODE http_conn::parse_content(char* text) {
    // 检查是否读取到了足够的主体内容
    if (m_read_idx >= (m_content_length + m_checked_idx)) {
        // 终止字符串,并将其赋值给m_string成员变量
        text[m_content_length] = '\0';
        m_string = text;
        // 请求解析完成,返回GET_REQUEST状态
        return GET_REQUEST;
    }
    // 请求解析未完成,返回NO_REQUEST状态
    return NO_REQUEST;
}

// 处理HTTP请求的主要函数
// 根据不同的URL请求来定位资源文件并进行相应的处理
http_conn::HTTP_CODE http_conn::do_request() {
    // 将doc_root路径复制到m_real_file中,作为基础路径
    strcpy(m_real_file, doc_root);
    // 获取基础路径的长度
    int len = strlen(doc_root);

    // 查找URL中的最后一个'/'字符
    const char* p = strrchr(m_url, '/');

    // 处理cgi请求
    if (cgi == 1 && (*(p + 1) == '2' || *(p+ 1) == '3')) {
        // 通过URL中的标志判断是登录验证还是注册验证
        char flag = m_url[1];

        // 动态构造真实的URL路径
        char *m_url_real = (char*) malloc(sizeof(char) * 200);
        strcpy(m_url_real, "/");
        strcat(m_url_real, m_url+ 2);
        strncpy(m_real_file + len, m_url_real,FILENAME_LEN - len - 1);
        free(m_url_real);

        // 提取用户名和密码
        char name[100], password[100];
        int i; 
        for (int i = 5; m_string[i] != '&'; ++i)
            name[i - 5] = m_string[i];
        name[i - 5 ] = '\0';

        int j = 0;
        for (j = i + 10; m_string[i] = '\0'; ++i, ++j) 
            password[j] = m_string[i];
        password[j] = '\0';

        // 处理注册请求
        if (*(p + 1) == '3') {
            // 检查数据库中是否有同名用户
            // 若没有,则插入新用户数据
            char* sql_insert = (char*)malloc(sizeof(char) * 200);
            strcpy(sql_insert, " INSERT INTO user (username, passwd) VALUES(");
            strcat(sql_insert, "'");
            strcat(sql_insert, name);
            strcat(sql_insert, "', '");
            strcat(sql_insert, password);
            strcat(sql_insert,"')");

            if (users.find(name) == users.end()){
                // 执行数据库插入操作
                m_lock.lock();
                int res = mysql_query(mysql, sql_insert);
                users.insert(pair<string, string> (name, password));
                m_lock.unlock();

                // 根据操作结果重定向用户
                if (!res) {
                    strcpy(m_url, "/log.html");
                }
                else {
                    strcpy(m_url, "/registerError.html");
                }


            }
            else {
                // 若已存在同名用户,重定向到注册错误页面
                strcpy(m_url, "/registerError.html");
            }

        }
        // 处理登录请求
        else if (*(p + 1) ==  '2') {
            // 验证用户名和密码
            if (users.find(name) != users.end() && users[name] == password) {
                strcpy(m_url, "/welcome.html");
            }
            else {
                strcpy(m_url, "/logError.html");
            }
        }

        // 其他特殊请求的处理
        if (*(p + 1) == '0') {
            char* m_url_real = (char*)malloc(sizeof(char) * 200);
            strcpy(m_url_real, "/register.html");
            strncpy(m_real_file + len, m_url_real, strlen(m_url_real));

            free(m_url_real);
        }
        else if (*(p + 1) == '1')
        {
            char *m_url_real = (char *)malloc(sizeof(char) * 200);
            strcpy(m_url_real, "/log.html");
            strncpy(m_real_file + len, m_url_real, strlen(m_url_real));

            free(m_url_real);
        }
        else if (*(p + 1) == '5')
        {
            char *m_url_real = (char *)malloc(sizeof(char) * 200);
            strcpy(m_url_real, "/picture.html");
            strncpy(m_real_file + len, m_url_real, strlen(m_url_real));

            free(m_url_real);
        }
        else if (*(p + 1) == '6')
        {
            char *m_url_real = (char *)malloc(sizeof(char) * 200);
            strcpy(m_url_real, "/video.html");
            strncpy(m_real_file + len, m_url_real, strlen(m_url_real));

            free(m_url_real);
        }
        else if (*(p + 1) == '7')
        {
            char *m_url_real = (char *)malloc(sizeof(char) * 200);
            strcpy(m_url_real, "/fans.html");
            strncpy(m_real_file + len, m_url_real, strlen(m_url_real));

            free(m_url_real);
        }
        // 默认情况,直接使用URL构造文件路径
        else
            strncpy(m_real_file + len, m_url, FILENAME_LEN - len - 1);
            
        }

    // 检查文件状态
    if (stat(m_real_file, &m_file_stat) < 0)
        return NO_RESOURCE;

    // 检查文件权限
    if (!(m_file_stat.st_mode & S_IROTH)) {
        return FORBIDDEN_REQUEST;
    }

    // 检查是否为目录
    if (S_ISDIR(m_file_stat.st_mode)) {
        return BAD_REQUEST;
    }

    // 打开文件并映射到内存
    int fd = open(m_real_file, O_RDONLY);
    m_file_address = (char* )mmap(0, m_file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    close(fd);
    return FILE_REQUEST;
}

参考

最新版Web服务器项目详解 - 12 注册登录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2101120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AquaCrop模型数据制备、优化方法、敏感性与气候变化影响分析及源码解析

AquaCrop是由世界粮食及农业组织&#xff08;FAO&#xff09;开发的一个先进模型&#xff0c;旨在研究和优化农作物的水分生产效率。这个模型在全球范围内被广泛应用于农业水管理&#xff0c;特别是在制定农作物灌溉计划和应对水资源限制方面显示出其强大的实用性。AquaCrop 不…

PySide6复杂C/S系统开发

PySide6复杂C/S系统开发 目录 0.了解 1.前提 2.实际代码&#xff08;继承QGraphicsview修改&#xff09; 0.了解 之前写了一篇“PySimpleGUI复杂C/S系统开发”博客&#xff08;由于pysimplegui更改了协议&#xff0c;因此不再推荐&#xff0c;用了pyside6后yyds&#xff09…

Transiting from CUDA to HIP (二)

一、Identifying Architecture Features 1. HIP_ARCH Defines 在 CUDA 编程中&#xff0c;__CUDA_ARCH__ 是一个预定义的宏&#xff0c;用于指示当前编译的代码所针对的 NVIDIA GPU 的计算能力&#xff08;Compute Capability&#xff09;。开发者可以使用这个宏来编写条件代…

Xinstall助力App推广:全方位支持,精准数据分析,你值得拥有

在如今的移动互联网时代&#xff0c;App推广已成为每个应用开发者必须面对的重要课题。然而&#xff0c;推广过程中往往伴随着诸多痛点&#xff0c;如数据混乱、投放盲目、决策滞后以及作弊困扰等。这些问题不仅影响了推广效果&#xff0c;还可能导致资源的浪费和投入产出不均衡…

数据安全认证来了解一下

随着数据安全法及个人信息保护法的实施&#xff0c;数据安全相关岗位在安全行业变得极为热门。 根据数据安全法第二十条&#xff0c;国家鼓励教育、科研机构和企业等开展数据开发利用技术和数据安全相关的教育和培训&#xff0c;采用多种途径培育专业人才&#xff0c;促进人才…

【Linux】使用Linux实现小程序 - 进度条

目录 一、缓冲区二、回车换行的概念三、进度条的设计3.1 版本1&#xff08;没有配合场景&#xff09;3.2 版本2&#xff08;配合场景&#xff09;3.3 版本3&#xff08;美化进度条&#xff09; 结尾 一、缓冲区 C/C语言&#xff0c;会针对标准输出&#xff0c;给我们提供默认的…

c++----杨辉三角(补充)

大家好。今天我给大家带来的是&#xff0c;我们以前讨论过的知识点。杨辉三角。我相信大家在c的学习中已经清楚的了解和认识到了杨辉三角的实现逻辑和实现方法了。但是应该大多局限于在c中吧。我们都知道我们c与c其实在一些地方是可以相互成就的。那么我们在c中的经典题目杨辉三…

自定义实现log4j的appender

log4j&#xff0c;应用最广泛的日志框架。其作者后来推出logback&#xff0c;也是好选择。不多说废话。 log4j组件介绍 Log4j主要有三个组件&#xff1a; Logger&#xff1a;负责供客户端代码调用&#xff0c;执行debug(Object msg)、info(Object msg)、warn(Object msg)、err…

oracle----undo表空间

文章目录 undo表空间概念和作用undo表空间主要用于解决&#xff1a;1.1 读一致性1.2 回滚事务1.3 实例恢复 undo表空间操作查看UNDO表空间查看UNDO 参数查看undo表空间文件位置 undo表空间概念和作用 对于DML语句&#xff0c;只要修改了数据块&#xff0c;数据库就会把修改前的…

使用Amazon SageMaker JumpStart微调Meta Llama 3.1模型以进行生成式AI推理

文章目录 使用Amazon SageMaker JumpStart微调Meta Llama 3.1模型以进行生成式AI推理Meta Llama 3.1SageMaker JumpStartSageMaker JumpStart中Meta Llama 3.1模型的微调配置使用SageMaker JumpStart UI进行无代码微调使用SageMaker JumpStart SDK进行微调结论 使用Amazon Sage…

电商数据整合新篇章:京东商品详情API返回值应用实践

电商数据整合在当今商业环境中具有重要地位&#xff0c;API&#xff08;应用程序编程接口&#xff09;提供了高效收集、整合和分析数据的途径。以京东商品详情API为例&#xff0c;通过其返回值&#xff0c;电商企业可以构建更精准的营销策略、优化产品以及提升用户体验。以下是…

实例分割【YOLOv8版】

参考文档 Segment - Ultralytics YOLO Docs​docs.ultralytics.com/tasks/segment/ 何为实例分割&#xff1f; 实例分割比目标检测更进一步&#xff0c;涉及识别图像中的各个对象并将它们与图像的其余部分分割开来。 实例分割模型的输出是一组用于勾勒图像中每个对象的掩码…

回溯法-图的m着色问题

图的 m 着色问题 问题描述 给定一个无向连通图 ( G (V, E) ) 和 ( m ) 种颜色&#xff0c;我们的任务是为图 ( G ) 的每个顶点着色&#xff0c;使得相邻的顶点颜色不同。如果存在这样的着色方案&#xff0c;我们称之为图 ( G ) 的 ( m ) 可着色问题。 算法思路 初始化&…

Sentence-BERT实现文本匹配【回归目标函数】

引言 上篇文章我们通过Sentence-Bert提出的分类目标函数来训练句子嵌入模型&#xff0c;本文同样基于Sentence-Bert的架构&#xff0c;但改用回归目标函数。 架构 如上图&#xff0c;计算两个句嵌入 u \pmb u u和 v \pmb v v​之间的余弦相似度&#xff0c;然后可以使用均方误…

如何通过住宅代理优化SERP表现:提升SEO排名的实用指南

引言 什么是SERP&#xff1f;包含哪些内容&#xff1f; 为什么SERP对SEO至关重要&#xff1f; 如何优化SERP表现&#xff1f; 总结 引言 在当今竞争激烈的数字营销环境中&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已成为企业提升在线可见性和吸引有机流量的关键…

matlab2024a/2023/2022/2020/matlab2019 如何plot画局部放大图(已解决)

matlab 2024&#xff1b;matlab 2023&#xff1b;matlab 2022&#xff1b;matlab 2021&#xff1b;matlab 2020&#xff1b;matlab 2019 matlab 2017一下的 使用magnify.m 进行局部放大图操作是没有问题的。 新版本 采用magnify.m 很难操作。 为什么要局部放大 局部方…

【王树森】Few-Shot Learning (3/3):Pretraining + Fine Tuning(个人向笔记)

Preliminary Few-Shot Learning 很简单&#xff0c;但是却能达到比较高的准确度&#xff0c;相反一些复杂的模型反而不能达到很高的准确率 1. Cosine Similarity 余弦相似度可以衡量两个向量的相似度 假设两个向量的长度都是1&#xff1a;那么它们余弦相似度的计算方法如下…

HarmonyOS开发实战( Beta5版)线程间通信场景最佳实践

简介 在应用开发中&#xff0c;经常会需要处理一些耗时的任务&#xff0c;如果全部放在主线程中执行就会导致阻塞&#xff0c;从而引起卡顿或者掉帧现象&#xff0c;降低用户体验&#xff0c;此时就可以将这些耗时操作放到子线程中处理。通常情况下&#xff0c;子线程可以独立…

bcftools报错|The sequence “chr1“ not defined in the header: chr1.recode.vcf

1、报错信息 The sequence "chr1" not defined in the header: chr1.recode.vcf (Quick workaround: index the file.) 所使用的命令&#xff0c;目的是想合并所提取的特定染色体。 bcftools concat -O v / -o varscan.indel_merged.vcf chr1.recode.vcf chr2.reco…

超好用的图纸加密软件排行榜 | 2024图纸加密软件的七款最优选择!

数字化设计日益普及的今天&#xff0c;图纸作为设计与工程的核心载体&#xff0c;其安全性成为了企业和设计师们最为关注的焦点之一。 面对日益复杂的数据泄露风险&#xff0c;如何有效地保护图纸文件的安全呢&#xff1f; 下面&#xff0c;我们就来探讨一下2024图纸加密软件的…