数字石大登陆函数

数字石大登陆函数

前言

故事时间:2020年下半年(具体时间忘记了😭)

当时刚刚下定决心要转专业,所以有好多新奇的想法不断涌现。就比如做一个一键请假的脚本,但是那就必须想办法登录上学校的e站通(一个教职工以及学生的办事平台)才能实现各种各样的想法。

所以最初的Python版本就开始提上日程了。后来,发现了一款鸿蒙的课程表APP做的很棒,但是没有适配我们学校,于是我又写了Java版。再后来,学了Flutter,要做一款疫情填报APP,于是写了Dart版。

准备

我们学校的网站是用的cas统一身份认证。

打开开发者工具后,在 网络 选项中勾选 保留日志 (如果不保留日志,页面跳转后会清空日志信息)。

输入账号密码后直接点击登陆。

点击登录后就到了最重要的一步,找到提交身份认证信息的请求。很明显,这个 login 请求就是我们要找的请求。

![image-20230306122559873](/Users/xushuo/Library/Application Support/typora-user-images/image-20230306122559873.png)

点开请求后找到负载,也就是我们提交的表单。发现里面并没有我们刚刚提交的密码,但是有一条是 rsa ,这说明我们的密码是在前端加密后发送至服务器的。

![image-20230306124352084](/Users/xushuo/Library/Application Support/typora-user-images/image-20230306124352084.png)

于是我打开了 源代码 选项卡,找到了登陆函数。从这里可以发现, ul 是账号的长度、 pl 是密码的长度、 lt 是id为 lt 的标签值、 rsa 是用 strEnc 函数加密后的返回值,登陆函数最后提交了表单。

![image-20230306124645694](/Users/xushuo/Library/Application Support/typora-user-images/image-20230306124645694.png)

我们现在需要找的就是lt标签值和 strEnc 函数。我们先找 lt 标签。

不出所料,果然在页面中发现了隐藏的信息。表单提交的所有内容都被隐藏放在了页面的最后。

![image-20230306125459649](/Users/xushuo/Library/Application Support/typora-user-images/image-20230306125459649.png)

然后在 des.js 文件中找到了加密函数 strEnc

![image-20230306125901560](/Users/xushuo/Library/Application Support/typora-user-images/image-20230306125901560.png)

现在所有内容都已经准备好了,根据我的分析,身份验证的表单内容应该是:

rsa: 加密算法通过账号密码以及lt字符串拼接加密后的一串字符串
ul: 账号长度
pl: 密码长度
lt: 登陆标识,每次刷新页面都会更新
execution: 登陆失败次数记录(因为会随我登陆失败次数增加而增加)
_eventId: 固定值submit

Python版

用到的库有 bs4 | requests | execjs ,其中 execjs 是用来调用js文件的,用来实现加密算法(重新用Python写一遍实在是太麻烦了)。

根据前面准备内容的思路来写代码,首先是要建立一个会话,访问登陆页面去获取各项信息(lt、execution、_eventId)。

session = requests.Session()
login_url = "http://cas.upc.edu.cn/cas/login"
response = session.get(url=login_url)
soup = BS(response.content,'lxml')
LT = re.findall('value="(.*?)"/',str(soup.find_all('input',id="lt")[0]))[0]
execution = re.findall('value="(.*?)"/',str(soup.find_all('input',attrs={'name': "execution"})[0]))[0]
_eventId = re.findall('value="(.*?)"/',str(soup.find_all('input',attrs={'name': "_eventId"})[0]))[0]

然后根据获取的信息以及账号密码,调用 des.js 文件中 strEnc 函数来加密。

des = execjs.compile(open("./des.js").read())
rsa = des.call("strEnc",user+password+LT,"1","2","3")

建立表单,发送请求。

data = {
    "rsa": rsa,
    "ul": len(user), "pl": len(password),
    "lt": LT, "execution": execution, "_eventId": _eventId
}
response = session.post(url=login_url,data=data,verify=False)

全部代码

import requests
import execjs
from bs4 import BeautifulSoup as BS
import re

requests.packages.urllib3.disable_warnings()

def login(user, password):
    session = requests.Session()
    login_url = "http://cas.upc.edu.cn/cas/login"
    response = session.get(url=login_url)
    soup = BS(response.content,'lxml')
    LT = re.findall('value="(.*?)"/',str(soup.find_all('input',id="lt")[0]))[0]
    execution = re.findall('value="(.*?)"/',str(soup.find_all('input',attrs={'name': "execution"})[0]))[0]
    _eventId = re.findall('value="(.*?)"/',str(soup.find_all('input',attrs={'name': "_eventId"})[0]))[0]

    des = execjs.compile(open("./des.js").read())
    rsa = des.call("strEnc",user+password+LT,"1","2","3")

    data = {
        "rsa": rsa,
        "ul": len(user),
        "pl": len(password),
        "lt": LT,
        "execution": execution,
        "_eventId": _eventId
    }
    response = session.post(url=login_url,data=data,verify=False)
    if response.status_code == 200 :
        print("登陆成功")
        return session
    else: print("登陆失败")

其他版本

写了,但是有点久远了~

LICENSED UNDER CC BY-NC-SA 4.0
Comment