diff --git a/crates/erp-health/src/service/banner_service.rs b/crates/erp-health/src/service/banner_service.rs index 2d63e39..4a1bdeb 100644 --- a/crates/erp-health/src/service/banner_service.rs +++ b/crates/erp-health/src/service/banner_service.rs @@ -19,8 +19,11 @@ use crate::state::HealthState; type HmacSha256 = Hmac; -/// 签名 URL 密钥占位符,生产环境通过配置注入 -const SIGN_URL_SECRET: &str = "CHANGE_ME_IN_PRODUCTION"; +/// 获取签名 URL 密钥:优先环境变量 ERP__STORAGE__SECRET_KEY,回退到开发默认值 +fn signing_secret() -> String { + std::env::var("ERP__STORAGE__SECRET_KEY") + .unwrap_or_else(|_| "dev-only-secret-key-change-in-production".to_string()) +} // --------------------------------------------------------------------------- // 查询 @@ -302,7 +305,8 @@ pub async fn list_public_banners( return None; } - let (token, expires) = generate_signed_url(&media.storage_path, SIGN_URL_SECRET, 3600); + let (token, expires) = + generate_signed_url(&media.storage_path, &signing_secret(), 3600); let image_url = format!( "{}{}?expires={}&token={}", base_url.trim_end_matches('/'), diff --git a/crates/erp-server/config/default.toml b/crates/erp-server/config/default.toml index 47c2372..972caf7 100644 --- a/crates/erp-server/config/default.toml +++ b/crates/erp-server/config/default.toml @@ -60,6 +60,8 @@ is_enabled = true [storage] upload_dir = "./uploads" max_file_size = "10MB" +# 签名 URL 密钥(生产环境必须通过 ERP__STORAGE__SECRET_KEY 环境变量设置) +secret_key = "dev-only-secret-key-change-in-production" [rate_limit] # Redis 不可达时是否拒绝请求(fail-close)。默认 true = 安全优先。 diff --git a/crates/erp-server/src/config.rs b/crates/erp-server/src/config.rs index e18bc66..6b39d39 100644 --- a/crates/erp-server/src/config.rs +++ b/crates/erp-server/src/config.rs @@ -127,6 +127,20 @@ pub struct StorageConfig { pub upload_dir: String, /// 单文件最大大小(如 "10MB") pub max_file_size: String, + /// 签名 URL 密钥(HMAC-SHA256) + #[serde(default = "default_secret_key")] + pub secret_key: String, +} + +fn default_secret_key() -> String { + #[cfg(debug_assertions)] + { + "dev-only-secret-key-change-in-production".to_string() + } + #[cfg(not(debug_assertions))] + { + panic!("ERP__STORAGE__SECRET_KEY 必须设置(生产环境不允许使用默认签名密钥)") + } } impl StorageConfig {