fix: Mock支付增加MOCK_PAY_KEY密钥验证(规则:支付宝优先>启用开关>请求头签名)
This commit is contained in:
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user