Skip to main content

lnu_elytra/method/
login.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2
3use serde::Serialize;
4
5use crate::{
6    Client,
7    error::{Error, R},
8    utils::{
9        EncPwd, PublicKey, ToHtml, UseInputValue,
10        macros::{debug, error, info, trace},
11    },
12};
13
14impl Client {
15    /// 登录
16    pub async fn login(&mut self, username: &str, password: &str) -> R {
17        info!("正在登录...");
18
19        trace!("加载登录页");
20
21        let doc = self.get(&Client::LOGIN_URL).send().await?.doc().await?;
22
23        trace!("解析登录页,获取csrftoken");
24
25        let csrftoken = doc.use_val(&Client::S_CSRFTOKEN)?;
26
27        debug!("csrftoken: {}", csrftoken);
28
29        trace!("获取公钥,使用公钥加密密码");
30
31        let mm = self
32            .get(&Client::PUBLIC_KEY_URL)
33            .send()
34            .await?
35            .json::<PublicKey>()
36            .await?
37            .into_rsa_key()?
38            .enc_pwd(password)?;
39
40        #[derive(Serialize, Debug)]
41        struct LoginData<'a> {
42            csrftoken: &'a str,
43            yhm: &'a str,
44            mm: &'a str,
45            language: &'a str,
46        }
47
48        let login_data = LoginData {
49            csrftoken: csrftoken,
50            yhm: username,
51            mm: &mm,
52            language: "zh_CN",
53        };
54
55        debug!("登录数据: {:?}", login_data);
56
57        let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis();
58
59        trace!("发送登录请求");
60
61        let login_res = self
62            .post(&Client::LOGIN_URL)
63            .query(&[("time", timestamp)])
64            .form(&login_data)
65            .send()
66            .await?;
67
68        let doc = login_res.doc().await?;
69
70        let u = doc.use_val(&Client::S_SESSION_USER_KEY)?;
71
72        debug!("SESSION_USER_KEY: {}", u);
73
74        if u != username {
75            error!("登录失败,用户名不匹配");
76            return Err(Error::LoginFailed);
77        }
78
79        info!("登录成功");
80
81        Ok(())
82    }
83}