feat(gateway): 登录成功后更新 Users.last_login(v0.5.1)
启用 handleLogin 中被注释的 last_login 更新:经 DbC::call_msg 以 "$now" 哨兵(db 日期适配层转为服务端 UTC 时间)写入,失败按惯例 THROW_EX_CUSTOM 抛 500 由 wrapper 统一处理。README 版本节同步 (原仍停留在 0.3.0-security)。
This commit is contained in:
1 parent
19d5b65625
commit
b07dbf2da5
3 files changed
+21
-19
No files matched your search
@@ -73,7 +73,7 @@
|
||||
- 内部 HTTP 服务,默认监听 127.0.0.1:8443,不再承载 TLS(TLS 已由 WAF 终止)。
|
||||
- 通过 `Server.tls = on/off` 配置切换 HTTPS/HTTP 模式([example.ini](gateway/example.ini)),独立部署时仍可启用 TLS。
|
||||
- **密码安全**:PBKDF2-HMAC-SHA256(10 万轮 + 16 字节随机盐),密码强度校验(8+ 字符、4 类中至少 3 类),常数时间比较防 timing attack。
|
||||
- **用户存储**:用户数据通过 pymsg/TCP 调用 `db:8005`(`DbC::call_msg`)存取,不再直连本地 SQLite。
|
||||
- **用户存储**:用户数据通过 pymsg/TCP 调用 `db:8005`(`DbC::call_msg`)存取,不再直连本地 SQLite;登录成功即更新 `Users.last_login`(`"$now"` 哨兵)。
|
||||
- **Token 机制**:`Base64(payload) + "_" + RSA-Sign(payload)`,默认 1 小时过期,验签通过才放行;RSA 密钥对启动时内存生成,重启后旧 Token 全部失效。
|
||||
- **Cookie 认证**:登录成功同时签发 `HttpOnly + Secure + SameSite=Lax` 的 `q4_token` Cookie;代理时无 `Authorization` 头则回退读 Cookie 验签,并向下游注入 `Authorization: Bearer`(下游零改动);`POST /logout` 清除 Cookie。公开目标(`Proxy.default`)不做凭证校验,避免旧 Cookie 影响公开页面。
|
||||
- **CAPTCHA**:`/captcha` 接口生成验证码(5 分钟过期、一次性使用),登录与注册均可选启用;`GET /captcha/image` 为 captcha 服务(pymsg/TCP :8009)的图形验证码代理路由。
|
||||
|
||||
+4
-2
@@ -226,12 +226,14 @@ gateway/
|
||||
|
||||
## 版本
|
||||
|
||||
`0.3.0-security`(见 [src/main.cpp:27](src/main.cpp#L27))。启动时打印:
|
||||
`0.5.1`(见 [src/main.cpp:29](src/main.cpp#L29))。启动时打印:
|
||||
|
||||
```
|
||||
Gateway 0.3.0-security started (PBKDF2 + CAPTCHA + RateLimit)
|
||||
Gateway 0.5.1 started
|
||||
```
|
||||
|
||||
近期变更:登录成功后通过 db 更新 `Users.last_login`(`"$now"` 哨兵,db 日期适配层转为服务端当前 UTC 时间;更新失败经 THROW_EX_CUSTOM 抛 500,与其他步骤一致)。
|
||||
|
||||
## 依赖
|
||||
|
||||
- C++20(`g++`)
|
||||
|
||||
+16
-16
@@ -26,7 +26,7 @@ using namespace qing;
|
||||
namespace json = boost::json;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
constexpr const char *_VER = "0.5.0";
|
||||
constexpr const char *_VER = "0.5.1";
|
||||
|
||||
//////////////////////////////////
|
||||
#include <sstream>
|
||||
@@ -811,21 +811,21 @@ http::response<http::string_body> handleLogin(
|
||||
//stmt_upd.bind_text(1, username);
|
||||
//stmt_upd.step();
|
||||
//
|
||||
// 新版调用db模块 无法通过DB上传时间戳目前
|
||||
//json::value jv_upd = {
|
||||
// {"action", "update"},
|
||||
// {"table", "Users"},
|
||||
// {"values", json::object{
|
||||
// {"last_login", LocalTime::getCurrent()},
|
||||
// }},
|
||||
// {"where", json::object{
|
||||
// {"username", username},
|
||||
// }}
|
||||
//};
|
||||
//auto jv_db_r = DbC::call_http(jv_upd);
|
||||
//auto obj_r = jv_db_r.as_object();
|
||||
//auto success = obj_r["success"].as_bool();
|
||||
//if (!success) THROW_EX_CUSTOM(HttpException, 2102, json::serialize(jv_db_r)+"Login (Update Step) Failed", 500, "/login");
|
||||
// 新版调用db模块:values 中的 "$now" 哨兵由 db 日期适配层替换为服务端当前 UTC 时间
|
||||
//(此前因 db 无法处理日期列而注释,dbv2 增加 _coerce_value 后可用)。
|
||||
json::value jv_upd = {
|
||||
{"action", "update"},
|
||||
{"table", "Users"},
|
||||
{"values", json::object{
|
||||
{"last_login", "$now"},
|
||||
}},
|
||||
{"where", json::object{
|
||||
{"username", username},
|
||||
}}
|
||||
};
|
||||
auto jv_upd_r = DbC::call_msg(jv_upd);
|
||||
if (!jv_upd_r.as_object()["success"].as_bool())
|
||||
THROW_EX_CUSTOM(HttpException, 2102, "Login (Update Step) Failed", 500, "/login");
|
||||
|
||||
|
||||
/* 生成令牌 */
|
||||
|
||||
Reference in new issue
Block a user