fix: handle wechat message url verification
This commit is contained in:
@@ -901,35 +901,15 @@ pub async fn handle_wechat_virtual_payment_message_push_verify(
|
||||
Ok(value) => value,
|
||||
Err(error) => return build_wechat_message_push_verify_error_response(error),
|
||||
};
|
||||
let signature = query
|
||||
.msg_signature
|
||||
.as_deref()
|
||||
.or(query.signature.as_deref())
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or("");
|
||||
let timestamp = query.timestamp.as_deref().map(str::trim).unwrap_or("");
|
||||
let nonce = query.nonce.as_deref().map(str::trim).unwrap_or("");
|
||||
let echostr = query.echostr.as_deref().map(str::trim).unwrap_or("");
|
||||
if signature.is_empty() || timestamp.is_empty() || nonce.is_empty() || echostr.is_empty() {
|
||||
return build_wechat_message_push_verify_error_response(WechatPayError::InvalidRequest(
|
||||
"微信消息推送校验参数不完整".to_string(),
|
||||
));
|
||||
}
|
||||
if !verify_wechat_message_push_signature(token, timestamp, nonce, echostr, signature) {
|
||||
return build_wechat_message_push_verify_error_response(WechatPayError::InvalidSignature(
|
||||
"微信消息推送校验签名无效".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
match decrypt_wechat_message_push_ciphertext(
|
||||
match resolve_wechat_message_push_verify_response(
|
||||
token,
|
||||
aes_key,
|
||||
echostr,
|
||||
state
|
||||
.config
|
||||
.wechat_mini_program_app_id
|
||||
.as_deref()
|
||||
.or(state.config.wechat_app_id.as_deref()),
|
||||
&query,
|
||||
) {
|
||||
Ok(plaintext) => (StatusCode::OK, plaintext).into_response(),
|
||||
Err(error) => build_wechat_message_push_verify_error_response(error),
|
||||
@@ -1139,6 +1119,50 @@ fn build_wechat_message_push_verify_error_response(error: WechatPayError) -> Res
|
||||
(StatusCode::BAD_REQUEST, message).into_response()
|
||||
}
|
||||
|
||||
fn resolve_wechat_message_push_verify_response(
|
||||
token: &str,
|
||||
aes_key: &str,
|
||||
expected_app_id: Option<&str>,
|
||||
query: &WechatMiniProgramMessagePushQuery,
|
||||
) -> Result<String, WechatPayError> {
|
||||
let timestamp = query.timestamp.as_deref().map(str::trim).unwrap_or("");
|
||||
let nonce = query.nonce.as_deref().map(str::trim).unwrap_or("");
|
||||
let echostr = query.echostr.as_deref().map(str::trim).unwrap_or("");
|
||||
if timestamp.is_empty() || nonce.is_empty() || echostr.is_empty() {
|
||||
return Err(WechatPayError::InvalidRequest(
|
||||
"微信消息推送校验参数不完整".to_string(),
|
||||
));
|
||||
}
|
||||
let msg_signature = query
|
||||
.msg_signature
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty());
|
||||
if let Some(signature) = msg_signature {
|
||||
if !verify_wechat_message_push_signature(token, timestamp, nonce, echostr, signature) {
|
||||
return Err(WechatPayError::InvalidSignature(
|
||||
"微信消息推送 msg_signature 无效".to_string(),
|
||||
));
|
||||
}
|
||||
return decrypt_wechat_message_push_ciphertext(aes_key, echostr, expected_app_id);
|
||||
}
|
||||
|
||||
let signature = query
|
||||
.signature
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| {
|
||||
WechatPayError::InvalidRequest("微信消息推送校验参数不完整".to_string())
|
||||
})?;
|
||||
if !verify_wechat_message_push_signature(token, timestamp, nonce, "", signature) {
|
||||
return Err(WechatPayError::InvalidSignature(
|
||||
"微信消息推送校验签名无效".to_string(),
|
||||
));
|
||||
}
|
||||
Ok(echostr.to_string())
|
||||
}
|
||||
|
||||
fn parse_wechat_mini_program_message_push_payload(
|
||||
body: &[u8],
|
||||
) -> Result<WechatMiniProgramEncryptedMessage, WechatPayError> {
|
||||
@@ -2217,6 +2241,31 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wechat_message_push_plain_get_verify_returns_echostr() {
|
||||
let token = "AAAAA";
|
||||
let timestamp = "1714036504";
|
||||
let nonce = "1514711492";
|
||||
let echostr = "4375120948345356249";
|
||||
let signature = "f464b24fc39322e44b38aa78f5edd27bd1441696";
|
||||
|
||||
let plaintext = resolve_wechat_message_push_verify_response(
|
||||
token,
|
||||
"unused-aes-key",
|
||||
Some("wx-test-app"),
|
||||
&WechatMiniProgramMessagePushQuery {
|
||||
signature: Some(signature.to_string()),
|
||||
timestamp: Some(timestamp.to_string()),
|
||||
nonce: Some(nonce.to_string()),
|
||||
echostr: Some(echostr.to_string()),
|
||||
msg_signature: None,
|
||||
},
|
||||
)
|
||||
.expect("plain url verification should return echostr");
|
||||
|
||||
assert_eq!(plaintext, echostr);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wechat_message_push_decrypts_safe_mode_ciphertext() {
|
||||
let app_id = "wx-test-app";
|
||||
|
||||
Reference in New Issue
Block a user