fix: Mock支付增加MOCK_PAY_KEY密钥验证(规则:支付宝优先>启用开关>请求头签名)

This commit is contained in:
2026-06-02 12:08:05 +08:00
parent 5d6be08f32
commit 2c0bdf18ce

View File

@@ -1024,20 +1024,50 @@ pub async fn create_order(
})))
}
/// 检查 Mock 支付是否允许
/// 规则(依次):
/// 1. 已配置支付宝 → 禁用(真实支付优先)
/// 2. MOCK_PAY_ENABLED != true → 禁用
/// 3. MOCK_PAY_KEY 已设置 → 验证 X-Mock-Key 请求头
fn check_mock_payment_allowed(req: &HttpRequest) -> Result<(), AppError> {
// 规则 1有支付宝时永不走 Mock
if AlipayConfig::from_env().is_some() {
return Err(AppError::BadRequest("真实支付已启用Mock 支付不可用".to_string()));
}
// 规则 2必须显式启用 Mock 支付
if std::env::var("MOCK_PAY_ENABLED").ok() != Some("true".to_string()) {
return Err(AppError::Forbidden("Mock 支付未启用".to_string()));
}
// 规则 3如果设了 MOCK_PAY_KEY验证请求头
if let Ok(key) = std::env::var("MOCK_PAY_KEY") {
if !key.is_empty() {
let header_key = req
.headers()
.get("X-Mock-Key")
.and_then(|v| v.to_str().ok())
.unwrap_or("");
if header_key != key {
return Err(AppError::Forbidden("Mock 支付密钥错误".to_string()));
}
}
}
Ok(())
}
/// POST /api/payment/mock-confirm
/// 仅在未配置支付宝时可用(否则用户可绕过真实支付
/// 所有 Mock 操作均需密钥授权(通过 MOCK_PAY_ENABLED + MOCK_PAY_KEY 控制
#[post("/api/payment/mock-confirm")]
pub async fn mock_confirm(
req: HttpRequest,
pool: web::Data<PgPool>,
claims: web::ReqData<Claims>,
body: web::Json<MockConfirmRequest>,
) -> Result<HttpResponse, AppError> {
check_payment_maintenance()?;
// 安全守卫:已配置支付宝时禁用 Mock 支付,防止绕过
if AlipayConfig::from_env().is_some() {
return Err(AppError::BadRequest("真实支付已启用Mock 支付不可用".to_string()));
}
check_mock_payment_allowed(&req)?;
let user_id = claims.user_id;
let expires_at =