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 小时前
Django
后端·python·django
FlightYe9 小时前
视界原理之3D视频(四):裸眼、眼镜和头显
android·linux·c++·3d·ffmpeg·音视频
利威尔xu9 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
逃逸线LOF10 小时前
Ribbon负载均衡原理(Irule组件、源码分析)
后端·spring cloud·ribbon
by2099910 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
慢云智慧空间10 小时前
从设备智能到空间理解,空间智能终端解决方案商如何重新定义行业标准
后端
利威尔xu10 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
Rover Ramble11 小时前
C++ 用互斥锁实现读写锁
开发语言·c++
你怎么知道我是队长11 小时前
C++零基础入门第2周:数据类型、运算符与表达式完全指南(附20段可运行代码+避坑清单)
c++
薛定谔的猫-菜鸟程序员11 小时前
软件架构设计师开发资料大全(从入门到精通)
后端·python·系统架构·flask·架构设计师