首页 > 其他分享 >【TinyWebServer】12注册登录

【TinyWebServer】12注册登录

时间:2023-10-06 21:26:08浏览次数:35  
标签:real 12 登录 url TinyWebServer char strcpy mysql 页面

整体概述

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

本文内容

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

流程图

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

1695544573739

载入数据库表

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

//用户名和密码
map<string, string> users;

void http_conn::initmysql_result(connection_pool *connPool)
{
    //先从连接池中取一个连接
    MYSQL *mysql = NULL;
    connectionRAII mysqlcon(&mysql, connPool);

    //在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(

	);

    //返回所有字段结构的数组
    MYSQL_FIELD *fields = mysql_fetch_fields(result);

    //从结果集中获取下一行,将对应的用户名和密码,存入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,进而提取出用户名和密码。

//判断http请求是否被完整读入
http_conn::HTTP_CODE http_conn::parse_content(char *text)
{
    if (m_read_idx >= (m_content_length + m_checked_idx))
    {
        text[m_content_length] = '\0';

        //POST请求中最后为输入的用户名和密码
        m_string = text;
        return GET_REQUEST;
    }
    return NO_REQUEST;
}

//根据标志判断是登录检测还是注册检测
char flag = m_url[1];

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);

//将用户名和密码提取出来
//user=123&password=123
char name[100], password[100];
int i;

//以&为分隔符,前面的为用户名
for (i = 5; m_string[i] != '&'; ++i)
    name[i - 5] = m_string[i];
name[i - 5] = '\0';

//以&为分隔符,后面的是密码
int j = 0;
for (i = i + 10; m_string[i] != '\0'; ++i, ++j)
    password[j] = m_string[i];
password[j] = '\0';

同步线程登录注册

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

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

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

const char *p = strrchr(m_url, '/');

if (0 == m_SQLVerify)
{
    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, "')");

        //判断map中能否找到重复的用户名
        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");
    }
    //如果是登录,直接判断
    //若浏览器端输入的用户名和密码在表中可以查找到,返回1,否则返回0
    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");
    }
}

页面跳转

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

  • 0
    • 跳转注册页面,GET
  • 1
    • 跳转登录页面,GET
  • 5
    • 显示图片页面,POST
  • 6
    • 显示视频页面,POST
  • 7
    • 显示关注页面,POST
//找到url中/所在位置,进而判断/后第一个字符
const char *p = strrchr(m_url, '/');

//注册页面
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);

转载文章:

最新版Web服务器项目详解 - 12 注册登录 (qq.com)

标签:real,12,登录,url,TinyWebServer,char,strcpy,mysql,页面
From: https://www.cnblogs.com/Wangzx000/p/17745040.html

相关文章

  • RK3588开发笔记(一):基于方案商提供的宿主机交叉编译Qt5.12.10
    前言  rk3588开发车机,方案上提供的宿主机只是编译rksdk的版本,并未编译好Qt,那么需要自行交叉编译Qt系统。选择的Qt的版本为5.12.10。 宿主机准备  下载并打开宿主机,只有sdk,并没有交叉编译的Qt。   Qt准备  下载Qt5.12.10的开源软件(方案商提供)。  ......
  • 38-12
    在一个递增有序的单链表中,有数值相同的元素存在。去掉数值相同的元素,是表中不再有重复的元素。双指针解决链表的百分之60的问题,三指针解决百分之80的问题,四指针解决百分之99的问题脑子不够,指针来凑#include<stdio.h>#include<stdlib.h>typedefstructnode{intdata......
  • [题解] CF1245D - Shichikuji and Power Grid
    CF1245D-ShichikujiandPowerGrid题目传送门题意在一个网格图中,有\(n\)个城市。目标是使得\(n\)个城市都通电。对于一个城市有电,要么选择在其位置建立发电站,要么和另一个有电的城市连线。对于城市\(i\),在其位置建立发电站的费用为\(c_i\),和另一个城市\(j\)连电......
  • 力扣-1512-好数对的数目
    给你一个整数数组nums。如果一组数字(i,j)满足nums[i]==nums[j]且i<j,就可以认为这是一组好数对。返回好数对的数目。 示例1:输入:nums=[1,2,3,1,1,3]输出:4解释:有4组好数对,分别是(0,3),(0,4),(3,4),(2,5),下标从0开始示例2:输入:nums=[1,1,1,1]输出......
  • ADG环境RAC主库在清理归档时出现RMAN-08120
    1、环境信息11gRAC+单节点ADG2、目的清理部分已应用过的归档,且清理之前保证主库所有归档已被应用3、异常信息--定时任务在清理过期归档时出现,但DG日志应用是正常的RMAN-08120:WARNING:archivedlognotdeleted,notyetappliedbystandbyarchivedlogfilename=+ARCH/t......
  • Minecraft个人服务器搭建自己的皮肤站并实现外置登录更换自定义皮肤组件
    Minecraft个人服务器搭建自己的皮肤站并实现外置登录更换自定义皮肤组件大家好,我是艾西有不少小伙伴非常喜欢我的世界Minecraft游戏,今天小编跟大家分享下Minecraft个人服务器怎么设置皮肤站。Minecraft皮肤站是什么?其实官网就有皮肤站,在正版用户选择正版的登录后,MC客户端就会到官方......
  • webapi 登录接口acctID参数获取SQL
    USEK3DBConfiger20216155555176selectA.FNUMBER,B.FNAME,A.FDATABASENAME,A.FDATACENTERIDFROMT_BAS_DATACENTERASALEFTJOINT_BAS_DATACENTER_LASBONA.FDATACENTERID=B.FDATACENTERIDANDA.FLANGUAGE=B.FLOCALEID FDATACENTERID字段......
  • java——redis随笔——实战——短信登录
    前言: 此章节用到的知识点:mybatisPlus ;参考网址:https://www.bilibili.com/video/BV1Xu411A7tL?p=7&vd_source=79bbd5b76bfd74c2ef1501653cee29d6  正常新建一个接口: 再新建这个接口的实现类:  修改接口: 修改实现类:  然后就可以注入并使用了:   ......
  • Windows2012上搭建帝国CMS网站步骤(一)
    1.点击左下角开始按钮,选择“服务器管理器”; 2.默认仪表盘选项,选择“添加角色和功能”; 3.直接下一步; 4.选择“基于角色或基于功能的安装”; 5.选择“从服务器池中选择服务器”,选定好服务器,下一步; 6.选择“Web服务器(IIS)”, 7.在弹出的弹窗中选择“添加工具”,然后下......
  • pig4cloud框架系列三:密码模式换取token(登录认证)
    1,通过apiFox或者postMan模拟调用接口,使用密码模式获取token 2,首先代码会先来到ProviderManager类的authenticate方法,也就是登录认证的入口 3,先到AuthenticationProvider接口,然后到AbstractUserDetailsAuthenticationProvider实现类的authenticate方法 4,authenticate方法......