記錄使用Python登錄浙江大學統一身份認證
- 2020 年 8 月 16 日
- 筆記
背景
現在每天要進行健康情況上報,但是因為經常睡過頭忘記打卡,於是想著寫一個程式來自動打卡。
統一身份認證
訪問健康情況上報頁面(//healthreport.zju.edu.cn/ncov/wap/default/index)後會先跳轉到登錄介面
輸入帳號密碼登陸以後會發送一個post請求
表單里一共有五項內容
可以看到,username就是學號,password不是密碼的明文,可能是經過了哈希或者加密,authcode一項為空不用管,_eventId應該是提交的意思,而最長的execution看不出有什麼含義。
通過查看網頁源程式碼,可以看到登錄表單中有一項
就是execution的內容,可以看出,每次請求頁面的時候會返回execution,在登錄時帶著這一項提交,作用可能是防止csrf攻擊(猜的)。
那麼就只剩下密碼這一個參數了。
如果前端通過js加密密碼,必然要先從input框中先獲取密碼的內容,於是先找到密碼框的html程式碼
然後在source中全文搜索password
關鍵字,發現login.js
中有一段這樣的程式碼
點開看看
可以看到這段程式碼先進行一些欄位檢查,再把密碼加密填寫回password
,最後再執行submit提交到後台。
繼續搜索加密中用到的RSAUtils
發現程式碼都放在security.js
中,繼續打開看看
這個文件包含了加密需要的程式碼,其中的演算法我不太了解,不過好在Python有pyexecjs這個神器,直接把程式碼扒下來調用就好了。
但是圖中需要的public_exponent
和Modulus
兩個參數還沒有找到,考慮到每次登錄提交的密碼內容都不一樣,所以猜測這兩個可能是通過時間戳生成或者請求來的?繼續搜索
原來是通過ajax請求了這兩個參數,再在network里找,果然找到了這個請求
應該是通過cookie將這次的登錄表單和這對參數聯繫起來,好奇後台是通過什麼演算法驗證的。
程式碼實現
現在整個登錄的流程已經梳理清楚了,開始使用程式碼實現
- 先訪問頁面並提取
execution
sess = requests.session() r = sess.get('//healthreport.zju.edu.cn/ncov/wap/default/index') execution = re.search('name="execution" value="(.*?)"', r.text).group(1)
- 獲取密碼加密需要的參數
r = sess.get('//zjuam.zju.edu.cn/cas/v2/getPubKey') modulus = r.json()['modulus'] exponent = r.json()['exponent']
- 加密密碼
ctx = execjs.compile(jscode) encrypted_password = ctx.call('encrypt', username, password)
- 發送登錄請求
data = { 'username': username, 'password': encrypted_password, 'authcode': '' 'execution': execution, '_eventId': 'submit' } r = sess.post(post_url, data=data)
之後就可以進行自動打卡的操作了。