DreamCity

愿你有一天,能与你最重要的人重逢

这篇博文主要讲述的是我在开发易班易伴云网薪签到自动化脚本时的经历。如果你想了解脚本如何使用,请移步 GitHub 仓库。传送门 >>>

这学期开始,我们学校要求每人每月要在易班连续签到 5 天并截图上报。

虽然之前也一直在被易班骚扰,但也不是太过分,每个月发几个帖子、点点赞就好,五分钟的事。但是这学期的要求真的让我觉得很(和谐),以往五分钟能做完的事被强行拉长到了五天,而且一旦其中有一天忘记签到,之前的签到的天数都会作废。于是乎,我只能写个脚本来对付咯。


先了解一下这个「网薪签到」是什么东西。这不是易班自带的那个签到(虽然那个也发网薪),而是易班旗下(大概?)的易伴云提供的网薪签到功能。相比于易班自带的签到功能,易伴云的网薪签到给予了学校更大的自由度和更强的数据统计功能。你可以在易班 App 首页找到易伴云的入口,再在易伴云里找到这个网薪签到。

yiban-index

yibanyun-index

通过抓包可以了解到,易班的手机 App 上的易伴云的部分基本就是个套壳浏览器,所以我只需要模仿抓到的包的内容向易伴云服务器发送 HTTP 请求即可完成签到。


易伴云的用户认证是通过易班的 OAuth 实现的(第一次打开网薪签到页面的时候易班有让确认授权),所以我们需要做的是拿到易班的登录信息。

我最开始是想通过 Fiddler 抓手机上易班 App 的包来获取易班的登录流程以及 HTTP 请求信息。但是易班的手机 App 虽然说做的很一般,但是在反破解这方面倒是做的很细,不论是 iOS 客户端还是 Android 客户端,在登录时都有代理检测,并且会验证服务端的 SSL 证书,完全没法 MITM。我当然知道我可以直接把已经抓到的包里的 Cookies 直接拿来用,但是一旦 Cookies 失效,我就要重新抓包,非常麻烦。

之后我想到的是反编译易班的 Android 客户端,想看看代码上易班是怎么实现的登录。但是易班的 Android 客户端有腾讯御安全的加固,而我没有任何的 Android 开发或者脱壳的经验,网上找到的一些脱壳工具要么就是完全脱不了腾讯的壳,要么就是要收费而且要价还不低。

就在我疯狂地搜索的时候,我找到了一篇分析易班网页版登录流程的文章。然后我转念一想,既然是 OAuth 实现的用户认证,易班客户端里易伴云的部分也就是个套壳浏览器,那我能不能直接在普通浏览器上打开签到页面完成签到呢?于是,一顿操作过后:

yibanyun-sign

简单说一下易班网页版的登录的流程:登录表单的 attributes 中包含一个由服务器生成的 RSA 公钥和生成公钥时的时间戳,用户点击登录按钮后,前端会通过 JavaScript 使用这个 RSA 公钥对用户的密码进行加密,再和时间戳一起发送给服务器,服务器验证无误之后再给客户端发 Cookies。

不过我遇到了个很奇怪的问题,如果获取 RSA 公钥和提交登录中间的时间间隔太短的话,易班服务器有可能会返回「pwd 长度必须在 6 至 20 之间」的错误。我目前的解决方法是在获得 RSA 公钥之后、提交登录之前睡 5s,不知道有没有更好的解决方案。


拿到登录信息之后就可以发起签到了。这部分没什么好说的,根据之前抓到的包,向对应的 HTTP API 发送一个 POST 请求就行了。

我还写了一个检查连续签到天数的功能。易伴云这个网薪签到没有单独的查询连续签到天数的 API,是通过 HTML 内联的 JavaScript 来在前端动态地修改连续签到天数的显示的。用 Beautiful Soup 库解析网页,然后用正则表达式匹配即可。未来有时间的话可能会再想办法实现「一旦达成连续签到目标就不再继续签到」的功能。因为易伴云这个网薪签到每月能发的网薪是有限额的,需要学校向易班申请,一旦配额用完就会出现无法签到的情况,损人不利己。

yibanyun-sign-failed


最后我用 Python 写了个自动化签到的脚本,Python 作为一个脚本语言来使用时还是很方便的。用 Requests 库的 Session API 来处理 HTTP 请求和 Cookies,用 Beautiful Soup 库来解析网页以获取登录时使用的 RSA 公钥、时间戳和连续签到天数。最后我小小地利用了一下 GitHub Actions,写了个定时的 Workflow,以实现全自动化签到。代码都放在 GitHub 仓库里了,MIT 开源,有需要的可以自己部署。

希望你我都能早日摆脱类似易班这种明明就是(和谐)却还使用行政手段强行喂给他人的东西。

参考链接

This article was last updated on days ago, and the information described in the article may have changed.