106
Server/SessionStore.cpp
Normal file
106
Server/SessionStore.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#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
|
Reference in New Issue
Block a user