成品展示:
(博主手殘黨)
暴雪爸爸在守望先鋒的官網上提供了一個生涯資料的查詢, 可惜沒有提供相關的API, “無法通過公開管道自由抓到完整資料”。
1.開發環境
httpclient抓取頁面資料
jsoup解析html
mozilla rhino執行js代碼
2。 抓包
使用fiddler抓包, 暴雪的登錄介面是
這裡面的csrftoken和sessionTimeout在頁面上有, useSrp、persistLogin、fp都是常量, password是預留位置
主要需要解決的問題就是publicA(公開金鑰)和clientEvidenceM1(憑據)
3.生成公開金鑰和憑據
不用在意publicA(公開金鑰)和clientEvidenceM1(憑據)的意義, 這兩個是從login.js的onSuccess方法中生成出來的。 其中login.js使用了srp.js的物件SrpClientSession, 直接使用rhino執行onSuccess的方法就行了。
(需要的moduls,generator等參數從一個csrf-token的api中獲取)
由於srp.js很大, rhino執行時很慢, 因此先用rhino compiler編譯成srp.class檔, 用PluginClassLoader動態載入進來執行。 編譯後的class是實現了Script介面的, 它有一個public Object exec(Context cx, Scriptable scope);方法, 用來執行自身。
4、附錄
a.非常重要的設置
HttpClient的Cookie不正確, 報invalid cookie header的錯誤。
RequestConfig.Builder builder = RequestConfig.custom; builder.setCookieSpec(CookieSpecs.STANDARD); RequestConfig config = builder.build; httpPost.setConfig(config); //httpGet.setConfig(config);b.創建classloader時, 應該使用AccessController.doPrivileged方法。
c.rhino的Context, Scope, Script應該在同一個執行緒中執行。
1 loginForm.csrfToken.val(e.csrf_token), this.password = this.inputPassword.val, 2 3 this.srpClientSession = new SrpClientSession(e.modulus, e.generator, e.hash_function), 4 5 6 this.srpClientCredentials = this.srpClientSession.step1(e.username, this.password, e.salt, e.public_B), 7 8 null !== this.password && this.inputPassword.val(Array(this.password.length + 1).join(this.passwordFill)), 9 10 this.inputUseSrp.val("true"), 11 this.inputPublicA.val(this.srpClientCredentials.publicA.toString(16)), 12 13 this.inputClientEvidenceM1.val(this.srpClientCredentials.clientEvidenceM1.toString(16))login.js的onSuccess方法
// 在原來的基礎上加了var navigator = {}; 以免rhino報錯 // https://github.com/xcr1234/overwatch/blob/master/src/main/resources/srp.jssrp.js
5。 問題
在登錄成功後自動跳轉(redirect)有問題, 目前只能手動跳轉