diff --git a/gateway/inc/LocalTime.hpp b/gateway/inc/LocalTime.hpp new file mode 100644 index 0000000..ca5cd42 --- /dev/null +++ b/gateway/inc/LocalTime.hpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +namespace qing { + +class LocalTime { +public: + // 获取当前本地时间字符串 + static std::string getCurrent(const std::string& format = "%Y-%m-%d %H:%M:%S") { + using namespace std::chrono; + auto now = system_clock::now(); + auto zone = current_zone(); + zoned_time zt{zone, now}; + return std::vformat(format, std::make_format_args(zt)); + } + + // 解析时间字符串为 system_clock::time_point(本地时间 → UTC) + static std::optional parse( + const std::string& str, + const std::string& format = "%Y-%m-%d %H:%M:%S" + ) { + using namespace std::chrono; + std::istringstream iss{str}; + local_time lt; + iss >> std::chrono::parse(format, lt); // ✅ 修复 + if (iss.fail()) { + return std::nullopt; + } + auto zone = current_zone(); + zoned_time zt{zone, lt}; + return zt.get_sys_time(); + } + + // ----- 过期判断 ----- + static bool isExpired(const std::chrono::system_clock::time_point& tp) { + using namespace std::chrono; + return system_clock::now() > tp; + } + + template + static bool isExpired(const std::chrono::system_clock::time_point& tp, + const std::chrono::duration& gracePeriod) { + using namespace std::chrono; + return system_clock::now() > tp + gracePeriod; + } + + static bool isExpired(const std::string& timeStr, + const std::string& format = "%Y-%m-%d %H:%M:%S") { + auto parsed = parse(timeStr, format); + if (!parsed) return true; + return isExpired(*parsed); + } + + template + static bool isExpired(const std::string& timeStr, + const std::chrono::duration& gracePeriod, + const std::string& format = "%Y-%m-%d %H:%M:%S") { + auto parsed = parse(timeStr, format); + if (!parsed) return true; + return isExpired(*parsed, gracePeriod); + } +}; + + +} diff --git a/gateway/src/main.cpp b/gateway/src/main.cpp index a36983c..ca8f9f6 100644 --- a/gateway/src/main.cpp +++ b/gateway/src/main.cpp @@ -12,6 +12,7 @@ #include #include #include "ExpBase.hpp" +#include "LocalTime.hpp" #include "Conf.hpp" using namespace pmc::net; @@ -328,7 +329,7 @@ http::response handleLogin( auto username = std::string(obj.at("username").as_string()); auto password = std::string(obj.at("password").as_string()); auto password_hash = SHA256::sha256(password); - std::cout << username << " " << password_hash << std::endl; + //std::cout << username << " " << password_hash << std::endl; std::string sql = "SELECT COUNT(*) FROM Users WHERE email=? AND password_hash=?;"; auto stmt = _SQLDB->stmt(sql); @@ -349,16 +350,17 @@ http::response handleLogin( //int created_at = 0; int keep_time = 3600; // second - json::value jv_r = { + /* 用于token的json对象 */ + json::value jv_t = { {"user", username}, - //{"created_at", created_at}, + {"created_at", LocalTime::getCurrent()}, {"keep_time", keep_time} }; - - std::string data = json::serialize(jv_r); + std::string data = json::serialize(jv_t); std::string token = Base64::base64_encode(data); std::string sign = _PRIV.Sign(data); + /* 用于返回结果的json对象 */ json::value jv_rr = { {"success", true}, {"data", json::object{{"token", token + "_" + sign}}} // 双大括号 @@ -484,6 +486,23 @@ http::response handleProxy( } } + json::value jv; + /* 令牌是否过期 */ + { + /* TODO: 放进try包裹 */ + jv = json::parse(auth); + json::object& obj = jv.as_object(); + + auto t = json::value_to(obj["created_at"]); + bool r = LocalTime::isExpired(t); + + if (r) { + THROW_EX_CUSTOM(HttpException, 2000, "Authorization Expired", + 401, "*"); + } + } + + /* 代理地址是否开放、合法 */ { std::cout << t_url << std::endl; bool flag = false;