fixbug
This commit is contained in:
1 parent
15a4bac484
commit
46b8f750ae
3 files changed
+31
-12
No files matched your search
@@ -125,6 +125,15 @@ default = http://127.0.0.1:9200
|
|||||||
closed = http://127.0.0.1:8005;http://127.0.0.1:8007;
|
closed = http://127.0.0.1:8005;http://127.0.0.1:8007;
|
||||||
opened = http://127.0.0.1:9200;http://127.0.0.1:8006;
|
opened = http://127.0.0.1:9200;http://127.0.0.1:8006;
|
||||||
|
|
||||||
|
[Token]
|
||||||
|
# Token 有效期(秒),默认 3600 = 1 小时
|
||||||
|
keep_time = 3600
|
||||||
|
|
||||||
|
[CORS]
|
||||||
|
# 允许跨域的 Origin 白名单(分号分隔)
|
||||||
|
# 仅命中的 Origin 才会回填 Access-Control-Allow-Origin;缺省为空(不回填)
|
||||||
|
allowed_origins = https://qsont.me;https://www.qsont.me;http://127.0.0.1:8443;http://localhost:8443
|
||||||
|
|
||||||
[Database]
|
[Database]
|
||||||
path = sqlite3.db
|
path = sqlite3.db
|
||||||
```
|
```
|
||||||
@@ -132,6 +141,8 @@ path = sqlite3.db
|
|||||||
- `Proxy.default`:未带 `Target-Url` header 时的默认转发地址(不需 Token,主要服务前端静态资源)。
|
- `Proxy.default`:未带 `Target-Url` header 时的默认转发地址(不需 Token,主要服务前端静态资源)。
|
||||||
- `Proxy.opened`:允许外部带 Token 访问的内部服务白名单(分号分隔)。
|
- `Proxy.opened`:允许外部带 Token 访问的内部服务白名单(分号分隔)。
|
||||||
- `Proxy.closed`:仅记录用途,实际靠"不在 opened 中即拒绝"实现隔离。
|
- `Proxy.closed`:仅记录用途,实际靠"不在 opened 中即拒绝"实现隔离。
|
||||||
|
- `Token.keep_time`:登录签发 Token 的有效期(秒),缺省 3600。
|
||||||
|
- `CORS.allowed_origins`:OPTIONS 预检允许跨域的 Origin 白名单(分号分隔),缺省为空(不回填 ACAO)。
|
||||||
|
|
||||||
## 部署模式
|
## 部署模式
|
||||||
|
|
||||||
|
|||||||
@@ -11,5 +11,14 @@ default = http://127.0.0.1:9200
|
|||||||
closed = http://127.0.0.1:8005;http://127.0.0.1:8007;
|
closed = http://127.0.0.1:8005;http://127.0.0.1:8007;
|
||||||
opened = http://127.0.0.1:9200;http://127.0.0.1:8006;
|
opened = http://127.0.0.1:9200;http://127.0.0.1:8006;
|
||||||
|
|
||||||
|
[Token]
|
||||||
|
# Token 有效期(秒),默认 3600 = 1 小时
|
||||||
|
keep_time = 3600
|
||||||
|
|
||||||
|
[CORS]
|
||||||
|
# 允许跨域的 Origin 白名单(分号分隔)
|
||||||
|
# 仅命中的 Origin 才会回填 Access-Control-Allow-Origin;缺省为空(不回填)
|
||||||
|
allowed_origins = https://qsont.me;https://www.qsont.me;http://127.0.0.1:8443;http://localhost:8443
|
||||||
|
|
||||||
[Database]
|
[Database]
|
||||||
path = sqlite3.db
|
path = sqlite3.db
|
||||||
+11
-12
@@ -37,8 +37,12 @@ std::vector<std::string> split(const std::string& s, char delim) {
|
|||||||
std::istringstream stream(s);
|
std::istringstream stream(s);
|
||||||
std::string token;
|
std::string token;
|
||||||
while (std::getline(stream, token, delim)) {
|
while (std::getline(stream, token, delim)) {
|
||||||
|
// 跳过空串:避免 "a;b;" 末尾分号产生 "" 元素
|
||||||
|
// 防御白名单匹配场景下空串被误判为命中
|
||||||
|
if (!token.empty()) {
|
||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +295,8 @@ static bool _TLS = false;
|
|||||||
static std::string _DEFT_URL;
|
static std::string _DEFT_URL;
|
||||||
static std::vector<std::string> _OPEN_URL;
|
static std::vector<std::string> _OPEN_URL;
|
||||||
static std::string _DB_PATH;
|
static std::string _DB_PATH;
|
||||||
|
static int _TOKEN_KEEP_TIME = 3600; // Token 有效期(秒),可由 [Token] keep_time 配置
|
||||||
|
static std::vector<std::string> _CORS_ORIGINS; // CORS 允许的 Origin 白名单,可由 [CORS] allowed_origins 配置
|
||||||
|
|
||||||
/* instance items */
|
/* instance items */
|
||||||
static std::unique_ptr<HttpServer> _SERVE;
|
static std::unique_ptr<HttpServer> _SERVE;
|
||||||
@@ -399,6 +405,8 @@ int main(int argc, char **argv) {
|
|||||||
_DEFT_URL = cf.get<std::string>("Proxy.default", "");
|
_DEFT_URL = cf.get<std::string>("Proxy.default", "");
|
||||||
_OPEN_URL = split(cf.get<std::string>("Proxy.opened", ""), ';');
|
_OPEN_URL = split(cf.get<std::string>("Proxy.opened", ""), ';');
|
||||||
_DB_PATH = cf.get<std::string>("Database.path", "");
|
_DB_PATH = cf.get<std::string>("Database.path", "");
|
||||||
|
_TOKEN_KEEP_TIME = cf.get<int>("Token.keep_time", 3600);
|
||||||
|
_CORS_ORIGINS = split(cf.get<std::string>("CORS.allowed_origins", ""), ';');
|
||||||
}
|
}
|
||||||
catch (ConfIni::IniConfigureFileParseException &e) {
|
catch (ConfIni::IniConfigureFileParseException &e) {
|
||||||
std::cerr << "ERROR: " << e.what() << std::endl;
|
std::cerr << "ERROR: " << e.what() << std::endl;
|
||||||
@@ -507,19 +515,12 @@ void registerRoutes(HttpServer &server) {
|
|||||||
pmc::net::http::response<pmc::net::http::string_body> res;
|
pmc::net::http::response<pmc::net::http::string_body> res;
|
||||||
res.result(pmc::net::http::status::ok);
|
res.result(pmc::net::http::status::ok);
|
||||||
|
|
||||||
// CORS 白名单(P1-4):仅允许官方域名,防止任意网站跨域调用
|
// CORS 白名单:从 [CORS] allowed_origins 加载,缺省为空(不回填 ACAO)
|
||||||
// 原配置 Access-Control-Allow-Origin: * 过宽,XSS 拿到 token 后可跨域读取数据
|
|
||||||
// 动态回填 Origin:仅当请求 Origin 命中白名单时才返回该值,否则不返回 ACAO 头
|
// 动态回填 Origin:仅当请求 Origin 命中白名单时才返回该值,否则不返回 ACAO 头
|
||||||
static const std::vector<std::string> allowed_origins = {
|
|
||||||
"https://qsont.me",
|
|
||||||
"https://www.qsont.me",
|
|
||||||
"http://127.0.0.1:8443", // 本地开发调试
|
|
||||||
"http://localhost:8443"
|
|
||||||
};
|
|
||||||
auto origin_it = req.base().find("Origin");
|
auto origin_it = req.base().find("Origin");
|
||||||
if (origin_it != req.base().end()) {
|
if (origin_it != req.base().end()) {
|
||||||
std::string origin = std::string(origin_it->value());
|
std::string origin = std::string(origin_it->value());
|
||||||
for (const auto& allowed : allowed_origins) {
|
for (const auto& allowed : _CORS_ORIGINS) {
|
||||||
if (origin == allowed) {
|
if (origin == allowed) {
|
||||||
res.set(pmc::net::http::field::access_control_allow_origin, origin);
|
res.set(pmc::net::http::field::access_control_allow_origin, origin);
|
||||||
res.set(pmc::net::http::field::vary, "Origin");
|
res.set(pmc::net::http::field::vary, "Origin");
|
||||||
@@ -709,12 +710,10 @@ http::response<http::string_body> handleLogin(
|
|||||||
|
|
||||||
auto _PRIV = MyRSA::Private_Key::from_pem(_KEYGEN->get_private_key_pem());
|
auto _PRIV = MyRSA::Private_Key::from_pem(_KEYGEN->get_private_key_pem());
|
||||||
|
|
||||||
int keep_time = 3600;
|
|
||||||
|
|
||||||
json::value jv_t = {
|
json::value jv_t = {
|
||||||
{"user", username},
|
{"user", username},
|
||||||
{"created_at", LocalTime::getCurrent()},
|
{"created_at", LocalTime::getCurrent()},
|
||||||
{"keep_time", keep_time}
|
{"keep_time", _TOKEN_KEEP_TIME}
|
||||||
};
|
};
|
||||||
std::string data = json::serialize(jv_t);
|
std::string data = json::serialize(jv_t);
|
||||||
std::string token = Base64::base64_encode(data);
|
std::string token = Base64::base64_encode(data);
|
||||||
|
|||||||
Reference in new issue
Block a user