前言
故事时间:2020年下半年(具体时间忘记了😭)
当时刚刚下定决心要转专业,所以有好多新奇的想法不断涌现。就比如做一个一键请假的脚本,但是那就必须想办法登录上学校的e站通(一个教职工以及学生的办事平台)才能实现各种各样的想法。
所以最初的Python版本就开始提上日程了。后来,发现了一款鸿蒙的课程表APP做的很棒,但是没有适配我们学校,于是我又写了Java版。再后来,学了Flutter,要做一款疫情填报APP,于是写了Dart版。
准备
我们学校的网站是用的cas统一身份认证。
打开开发者工具后,在 网络 选项中勾选 保留日志 (如果不保留日志,页面跳转后会清空日志信息)。
输入账号密码后直接点击登陆。
点击登录后就到了最重要的一步,找到提交身份认证信息的请求。很明显,这个 login 请求就是我们要找的请求。
 ](https://freell.top/usr/uploads/2023/03/1515917059.png)
点开请求后找到负载,也就是我们提交的表单。发现里面并没有我们刚刚提交的密码,但是有一条是 rsa ,这说明我们的密码是在前端加密后发送至服务器的。
 ](https://freell.top/usr/uploads/2023/03/2363584952.png)
于是我打开了 源代码 选项卡,找到了登陆函数。从这里可以发现, ul 是账号的长度、 pl 是密码的长度、 lt 是id为 lt 的标签值、 rsa 是用 strEnc 函数加密后的返回值,登陆函数最后提交了表单。
 ](https://freell.top/usr/uploads/2023/03/4105657883.png)
我们现在需要找的就是lt标签值和 strEnc 函数。我们先找 lt 标签。
不出所料,果然在页面中发现了隐藏的信息。表单提交的所有内容都被隐藏放在了页面的最后。
 ](https://freell.top/usr/uploads/2023/03/633742633.png)
然后在 des.js 文件中找到了加密函数 strEnc。
 ](https://freell.top/usr/uploads/2023/03/1355321241.png)
现在所有内容都已经准备好了,根据我的分析,身份验证的表单内容应该是:
rsa: 加密算法通过账号密码以及lt字符串拼接加密后的一串字符串
ul: 账号长度
pl: 密码长度
lt: 登陆标识,每次刷新页面都会更新
execution: 登陆失败次数记录(因为会随我登陆失败次数增加而增加)
_eventId: 固定值submitPython版
用到的库有 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("登陆失败")其他版本
写了,但是有点久远了~