async_wechat/official_account/
signature.rs1use serde::{Deserialize, Serialize};
2use sha1::{Digest, Sha1};
3
4use crate::OfficialAccount;
5
6#[cfg(test)]
7mod tests {
8 use crate::official_account::signature;
9
10 #[tokio::test]
11 async fn request_validate() {
12 let sha1 = "3baae9808b7f85925be470f303cc7b5d035a1c1c".to_string();
13 let sha2 = signature::signature("wechat", "1744100071", "952645420");
14
15 println!("签名: {}", sha1 == sha2);
16 }
17}
18
19#[derive(Debug, Serialize, Deserialize)]
20pub struct WechatQuery {
21 timestamp: String,
22 nonce: String,
23 signature: String,
24 echostr: Option<String>, }
26
27impl OfficialAccount {
28 pub async fn request_validate(&self, query: WechatQuery) -> bool {
39 let sha1 = signature(&self.config.token, &query.timestamp, &query.nonce);
40 sha1 == query.signature
41 }
42}
43
44pub fn signature(token: &str, timestamp: &str, nonce: &str) -> String {
46 let mut params = vec![token.to_string(), timestamp.to_string(), nonce.to_string()];
47 params.sort();
48
49 let combined = params.join("");
50
51 let mut hasher = Sha1::new();
52 hasher.update(combined.as_bytes());
53 let result = hasher.finalize();
54
55 format!("{:x}", result)
56}