rust_wechat_weapp/api/
auth.rs

1use crate::MiniProgramError;
2use rust_wechat_codegen::ServerResponse;
3use rust_wechat_core::client::ClientTrait;
4use rust_wechat_core::utils::hmac_sha256;
5use serde::{Deserialize, Serialize};
6
7const CODE2SESSION_URL: &str = "https://api.weixin.qq.com/sns/jscode2session";
8const CHECK_SESSION_URL: &str = "https://api.weixin.qq.com/wxa/checksession";
9const RESET_USER_SESSION_URL: &str = "https://api.weixin.qq.com/wxa/resetusersessionkey";
10
11#[derive(Debug, Serialize, Deserialize, ServerResponse)]
12#[sr(flatten)]
13pub struct Code2Session {
14    pub openid: String,
15    pub session_key: String,
16    pub unionid: Option<String>,
17}
18
19#[derive(Debug, Serialize, Deserialize, ServerResponse)]
20pub struct CheckSessionKey;
21
22#[derive(Debug, Serialize, Deserialize, ServerResponse)]
23pub struct SessionKey {
24    pub openid: String,
25    pub session_key: String,
26}
27
28impl crate::Client {
29    pub async fn code2session(&self, js_code: &str) -> crate::Result<Code2Session> {
30        let response: Code2SessionResponse = self
31            .get(
32                CODE2SESSION_URL,
33                &[
34                    ("grant_type", "authorization_code"),
35                    ("appid", &self.appid),
36                    ("secret", &self.secret),
37                    ("js_code", js_code),
38                ],
39            )
40            .await?;
41        Ok(response.data()?)
42    }
43
44    pub async fn check_session_key(&self, open_id: &str, signature: &str) -> crate::Result<()> {
45        let access_token = self.access_token().await?;
46        let signature = hmac_sha256(signature.as_bytes(), "")
47            .map_err(|err| MiniProgramError::CommonError(err.to_string()))?;
48
49        let response: CheckSessionKeyResponse = self
50            .get(
51                CHECK_SESSION_URL,
52                &[
53                    ("sig_method", "hmac_sha256"),
54                    ("access_token", &access_token),
55                    ("open_id", open_id),
56                    (
57                        "signature",
58                        String::from_utf8(signature)
59                            .map_err(|err| MiniProgramError::CommonError(err.to_string()))?
60                            .as_str(),
61                    ),
62                ],
63            )
64            .await?;
65        Ok(response.ignore()?)
66    }
67
68    pub async fn reset_user_session_key(
69        &self,
70        open_id: &str,
71        signature: &str,
72    ) -> crate::Result<SessionKey> {
73        let access_token = self.access_token().await?;
74        let signature = hmac_sha256(signature.as_bytes(), "")
75            .map_err(|err| MiniProgramError::CommonError(err.to_string()))?;
76
77        let response: SessionKeyResponse = self
78            .get(
79                RESET_USER_SESSION_URL,
80                &[
81                    ("sig_method", "hmac_sha256"),
82                    ("access_token", &access_token),
83                    ("open_id", open_id),
84                    (
85                        "signature",
86                        String::from_utf8(signature)
87                            .map_err(|err| MiniProgramError::CommonError(err.to_string()))?
88                            .as_str(),
89                    ),
90                ],
91            )
92            .await?;
93        Ok(response.data()?)
94    }
95}