Older/SessionStore.cpp
2025-03-01 09:09:30 +00:00

106 lines
3.0 KiB
C++

#include "SessionStore.h"
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
namespace Older {
SessionStore::SessionStore(boost::asio::io_context &ioContext) : m_ioContext(ioContext), m_cleanupTimer(ioContext) {
startCleanupTask();
}
std::string SessionStore::addSession(int userId, std::chrono::minutes sessionLifetime, std::chrono::minutes refreshInterval) {
using namespace boost::uuids;
using namespace std::chrono;
std::unique_lock lock(m_mutex);
random_generator uuid_gen;
auto now = system_clock::now();
SessionData data{userId,
to_string(uuid_gen()), // 生成刷新令牌
now + sessionLifetime, now + refreshInterval};
std::string access_token = to_string(uuid_gen());
m_sessions[access_token] = data;
m_refreshMap[data.refreshToken] = access_token;
return access_token;
}
void SessionStore::removeSession(const std::string &token) {
std::unique_lock lock(m_mutex);
auto it = m_sessions.find(token);
if (it != m_sessions.end()) {
m_refreshMap.erase(it->second.refreshToken);
m_sessions.erase(it);
}
}
std::pair<bool, std::string> SessionStore::validateAndRefresh(const std::string &token) {
using namespace std::chrono;
using namespace boost::uuids;
std::unique_lock lock(m_mutex);
auto it = m_sessions.find(token);
if (it == m_sessions.end()) return {false, ""};
auto now = system_clock::now();
SessionData &data = it->second;
if (now > data.expireTime) { // 检查是否过期
m_sessions.erase(it);
m_refreshMap.erase(data.refreshToken);
return {false, ""};
}
std::string newToken = token;
if (now > data.refreshTime) { // 检查是否需要刷新
random_generator uuid_gen;
newToken = to_string(uuid_gen());
// 保留刷新令牌
SessionData newData = data;
newData.refreshTime = now + minutes{15};
m_sessions.erase(it);
m_sessions[newToken] = newData;
m_refreshMap[data.refreshToken] = newToken;
}
return {true, newToken};
}
SessionData SessionStore::at(const std::string &token) {
SessionData ret;
if (m_sessions.count(token) > 0) {
ret = m_sessions.at(token);
}
return ret;
}
void SessionStore::startCleanupTask() {
using namespace std::chrono_literals;
m_cleanupTimer.expires_after(5min);
m_cleanupTimer.async_wait([this](boost::system::error_code ec) {
if (!ec) {
cleanupExpiredSessions();
startCleanupTask();
}
});
}
void SessionStore::cleanupExpiredSessions() {
using namespace std::chrono;
std::unique_lock lock(m_mutex);
auto now = system_clock::now();
for (auto it = m_sessions.begin(); it != m_sessions.end();) {
if (now > it->second.expireTime) {
m_refreshMap.erase(it->second.refreshToken);
it = m_sessions.erase(it);
} else {
++it;
}
}
}
} // namespace Older