Qt C++ http服务器安全登录token生成管理

一、前言

搭建HTTP服务器后,部署在公网服务器上时需要保证一定的安全性,这里将介绍最基本的登录验证后如何生成限时token来验证后续的请求消息。在Qt中可以使用#include 来生成通用唯一识别码,可以以此来生成token。如果需要提升安全性,可以使用QCryptographicHash::hash()来进行二次处理。

二、头文件定义说明

头文件代码如下,这里只使用QUuid生成唯一识别码来作为token,其中TOKEN_TIMEOUT_SECONDS定了token的生效时长,lastActiveTime定义了token的激活时间,后续以此来判断token是否失效。

C++ 复制代码
#ifndef TOKENMANAGER_H
#define TOKENMANAGER_H

#include <QObject>
#include <QMap>
#include <QDateTime>
#include <QUuid>
#include <QMutex>

#define TOKEN_TIMEOUT_SECONDS (12 * 60 * 60) // 12小时

struct TokenInfo
{
    QString username;
    QDateTime lastActiveTime;
};

class TokenManager
{
public:
    static TokenManager& instance()
    {
        static TokenManager ins;
        return ins;
    }

    QString createToken(const QString& username);
    bool validateToken(const QString& token);
    void removeExpiredTokens();

private:
    TokenManager() {}
    QMap<QString, TokenInfo> m_tokenMap;
    QMutex m_mutex;
};

#endif

三、源文件的定义

代码如下,实现三个函数,createToken()创建token,validateToken()查看token是否正确,removeExpiredTokens()清理失效的token。

C++ 复制代码
#include "TokenManager.h"

QString TokenManager::createToken(const QString& username)
{
    QString token = QUuid::createUuid().toString().remove("{").remove("}");
    //如果需要提高安全性
//    QByteArray raw = QUuid::createUuid().toByteArray();
//    QString token = QCryptographicHash::hash(raw, QCryptographicHash::Sha256).toHex();

    TokenInfo info;
    info.username = username;
    info.lastActiveTime = QDateTime::currentDateTime();

    QMutexLocker locker(&m_mutex);
    m_tokenMap[token] = info;
    return token;
}

bool TokenManager::validateToken(const QString& token)
{
    //暂时废弃token
//    return true;

    QMutexLocker locker(&m_mutex);

    if (!m_tokenMap.contains(token))
        return false;

    TokenInfo &info = m_tokenMap[token];

    if (info.lastActiveTime.secsTo(QDateTime::currentDateTime()) > TOKEN_TIMEOUT_SECONDS)
    {
        m_tokenMap.remove(token);
        return false;
    }

    // 刷新活跃时间
    info.lastActiveTime = QDateTime::currentDateTime();
    return true;
}

void TokenManager::removeExpiredTokens()
{
    QMutexLocker locker(&m_mutex);
    QList<QString> keys = m_tokenMap.keys();
    for (const QString& key : keys){
        if (!validateToken(key)){
            m_tokenMap.remove(key);
        }
    }
}

四、补充说明

从上面的源码中可以看到没有调用removeExpiredTokens()来清理token,这是因为这里是测试,如果正式使用时可以使用定时器定时清理失效的token,代码如下,推荐1小时一次:

C++ 复制代码
QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, [](){
    TokenManager::instance().removeExpiredTokens();
});
timer->start(3600000);
相关推荐
苏宸啊8 小时前
IPC管道
linux·c++
jeffer_liu9 小时前
Spring AI 生产级实战:裁判员
java·人工智能·后端·spring·大模型
爱思考的小伙9 小时前
Qt-03:串口助手
qt
BestOrNothing_20159 小时前
ROS2 话题通信实战:消息对象、Publisher 发布器与 Subscriber 订阅器保姆级教程
c++·ros2·subscriber·publisher·话题通信
金銀銅鐵9 小时前
用 Tkinter 实现简单的猜数字游戏
后端·python
copyer_xyf10 小时前
Python 模块与包的导入导出
前端·后端·python
夜微凉410 小时前
三、Spring
java·后端·spring
copyer_xyf10 小时前
Python venv 虚拟环境
前端·后端·python
艾iYYY10 小时前
string 类的模拟实现
android·服务器·c语言·c++·算法
为何创造硅基生物10 小时前
C++ virtual void StartNetwork() = 0; // 纯虚:子类必须实现,否则不能 new。
c++