wx_sdk/mp/
sns.rs

1use crate::{access_token::AccessTokenProvider, error::CommonResponse, SdkResult, WxSdk};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize)]
5pub struct GrantAccessToken {
6    access_token: String,
7    expires_in: u32,
8    refresh_token: String,
9    openid: String,
10    scope: String,
11}
12
13#[derive(Debug, Serialize, Deserialize)]
14pub struct UserInfo {
15    openid: String,
16    nickname: String,
17    sex: u8,
18    province: String,
19    city: String,
20    country: String,
21    headimgurl: String,
22    privilege: Option<Vec<String>>,
23    unionid: Option<String>,
24}
25
26pub struct SnsModule<'a, T: AccessTokenProvider>(pub(crate) &'a WxSdk<T>);
27
28impl<'a, T: AccessTokenProvider> SnsModule<'a, T> {
29    /// 微信网页授权
30    /// 详情请参考[微信官方文档](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html)
31    /// 第二步,通过code换取access token
32    pub async fn oauth_access_token(&self, code: String) -> SdkResult<GrantAccessToken> {
33        let base_url = "https://api.weixin.qq.com/sns/oauth2/access_token";
34        let client = self.0.http_client.get(base_url);
35
36        let app_id = self.0.app_id.clone();
37        let app_secret = self.0.app_secret.clone();
38        let client = client.query(&[
39            ("appid", app_id),
40            ("secret", app_secret),
41            ("code", code),
42            ("grant_type", "authorization_code".to_owned()),
43        ]);
44        let res: CommonResponse<GrantAccessToken> = client.send().await?.json().await?;
45        res.into()
46    }
47    /// 微信网页授权
48    /// 第三步:刷新access_token(如果需要)
49    pub async fn oauth_refresh_token(&self, refresh_token: String) -> SdkResult<GrantAccessToken> {
50        let base_url = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
51        let client = self.0.http_client.get(base_url);
52
53        let app_id = self.0.app_id.clone();
54        let client = client.query(&[
55            ("appid", app_id),
56            ("refresh_token", refresh_token),
57            ("grant_type", "refresh_token".to_owned()),
58        ]);
59        let res: CommonResponse<GrantAccessToken> = client.send().await?.json().await?;
60        res.into()
61    }
62
63    /// 微信网页授权
64    /// 拉取用户信息(需scope为 snsapi_userinfo)
65    pub async fn userinfo(
66        &self,
67        openid: String,
68        access_token: String,
69        lang: String,
70    ) -> SdkResult<UserInfo> {
71        let base_url = "https://api.weixin.qq.com/sns/userinfo";
72        let client = self.0.http_client.get(base_url);
73
74        let client = client.query(&[
75            ("access_token", access_token),
76            ("openid", openid),
77            ("lang", lang),
78        ]);
79        let res: CommonResponse<UserInfo> = client.send().await?.json().await?;
80        res.into()
81    }
82}