加入token时间验证
This commit is contained in:
1 parent
0399715008
commit
798d5afc4d
2 files changed
+91
-5
No files matched your search
@@ -0,0 +1,67 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
#include <format>
|
||||||
|
#include <optional>
|
||||||
|
#include <sstream>
|
||||||
|
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<std::chrono::system_clock::time_point> 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<seconds> 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 <typename Rep, typename Period>
|
||||||
|
static bool isExpired(const std::chrono::system_clock::time_point& tp,
|
||||||
|
const std::chrono::duration<Rep, Period>& 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 <typename Rep, typename Period>
|
||||||
|
static bool isExpired(const std::string& timeStr,
|
||||||
|
const std::chrono::duration<Rep, Period>& gracePeriod,
|
||||||
|
const std::string& format = "%Y-%m-%d %H:%M:%S") {
|
||||||
|
auto parsed = parse(timeStr, format);
|
||||||
|
if (!parsed) return true;
|
||||||
|
return isExpired(*parsed, gracePeriod);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+24
-5
@@ -12,6 +12,7 @@
|
|||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <openssl/provider.h>
|
#include <openssl/provider.h>
|
||||||
#include "ExpBase.hpp"
|
#include "ExpBase.hpp"
|
||||||
|
#include "LocalTime.hpp"
|
||||||
#include "Conf.hpp"
|
#include "Conf.hpp"
|
||||||
|
|
||||||
using namespace pmc::net;
|
using namespace pmc::net;
|
||||||
@@ -328,7 +329,7 @@ http::response<http::string_body> handleLogin(
|
|||||||
auto username = std::string(obj.at("username").as_string());
|
auto username = std::string(obj.at("username").as_string());
|
||||||
auto password = std::string(obj.at("password").as_string());
|
auto password = std::string(obj.at("password").as_string());
|
||||||
auto password_hash = SHA256::sha256(password);
|
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=?;";
|
std::string sql = "SELECT COUNT(*) FROM Users WHERE email=? AND password_hash=?;";
|
||||||
auto stmt = _SQLDB->stmt(sql);
|
auto stmt = _SQLDB->stmt(sql);
|
||||||
@@ -349,16 +350,17 @@ http::response<http::string_body> handleLogin(
|
|||||||
//int created_at = 0;
|
//int created_at = 0;
|
||||||
int keep_time = 3600; // second
|
int keep_time = 3600; // second
|
||||||
|
|
||||||
json::value jv_r = {
|
/* 用于token的json对象 */
|
||||||
|
json::value jv_t = {
|
||||||
{"user", username},
|
{"user", username},
|
||||||
//{"created_at", created_at},
|
{"created_at", LocalTime::getCurrent()},
|
||||||
{"keep_time", keep_time}
|
{"keep_time", keep_time}
|
||||||
};
|
};
|
||||||
|
std::string data = json::serialize(jv_t);
|
||||||
std::string data = json::serialize(jv_r);
|
|
||||||
std::string token = Base64::base64_encode(data);
|
std::string token = Base64::base64_encode(data);
|
||||||
std::string sign = _PRIV.Sign(data);
|
std::string sign = _PRIV.Sign(data);
|
||||||
|
|
||||||
|
/* 用于返回结果的json对象 */
|
||||||
json::value jv_rr = {
|
json::value jv_rr = {
|
||||||
{"success", true},
|
{"success", true},
|
||||||
{"data", json::object{{"token", token + "_" + sign}}} // 双大括号
|
{"data", json::object{{"token", token + "_" + sign}}} // 双大括号
|
||||||
@@ -484,6 +486,23 @@ http::response<http::string_body> handleProxy(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json::value jv;
|
||||||
|
/* 令牌是否过期 */
|
||||||
|
{
|
||||||
|
/* TODO: 放进try包裹 */
|
||||||
|
jv = json::parse(auth);
|
||||||
|
json::object& obj = jv.as_object();
|
||||||
|
|
||||||
|
auto t = json::value_to<std::string>(obj["created_at"]);
|
||||||
|
bool r = LocalTime::isExpired(t);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
THROW_EX_CUSTOM(HttpException, 2000, "Authorization Expired",
|
||||||
|
401, "*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代理地址是否开放、合法 */
|
||||||
{
|
{
|
||||||
std::cout << t_url << std::endl;
|
std::cout << t_url << std::endl;
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
|
|||||||
Reference in new issue
Block a user