注册登陆(最新版)

整体概述

本项目中,使用数据库连接池实现服务器访问数据库的功能,使用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 注册登录

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue 3和TypeScript中实现登录和注册功能,你可以按照以下步骤进行操作: 1. 安装Vue CLI:首先,确保你已经安装了最新版本的Vue CLI。你可以使用以下命令进行安装: ```shell npm install -g @vue/cli ``` 2. 创建Vue项目:使用Vue CLI创建一个新的Vue项目。你可以执行以下命令: ```shell vue create my-project ``` 在创建项目的过程中,选择Vue 3和TypeScript作为预设。 3. 创建登录和注册组件:在src目录下创建Login.vue和Register.vue组件,用于实现登录和注册功能。你可以使用Vue的单文件组件语法编写这两个组件。 4. 添加路由:在src目录下创建router目录,并在其中创建index.ts文件。在index.ts文件中配置Vue Router路由信息,将登录和注册组件与对应的路由路径进行关联。 5. 实现登录和注册逻辑:在Login.vue和Register.vue组件中,编写相应的模板、样式和逻辑代码,实现登录和注册的功能。你可以使用Vue的数据绑定、事件处理等特性来处理用户输入和与后端的交互。 6. 调用后端接口:在登录和注册逻辑中,你需要与后端进行数据交互。你可以使用Vue提供的axios或fetch等库来发送HTTP请求,并处理后端返回的数据。 7. 配置类型定义:在TypeScript中,你可以为Vue组件、数据模型等定义类型,以提高代码的可靠性和可维护性。你可以在组件中使用interface或type关键字定义类型,并在相关地方进行类型注解。 8. 测试和调试:完成以上步骤后,你可以在开发服务器上运行Vue项目,并通过浏览器访问登录和注册页面。在开发过程中,你可以使用Vue开发者工具来调试和检查组件状态、数据变化等情况。 上述步骤只是一个简单的登录和注册实现示例,具体的实现方式可能因个人需求和业务逻辑而有所差异。在实际开发中,你可以根据具体情况进行适当调整和优化。 另外,为了保证安全性,请确保在进行用户认证和密码存储时采取适当的安全措施,比如使用加密算法对密码进行哈希处理等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值