問題描述
近日在使用電腦處理文字的時候,發現 Windows 10 自帶的輸入法開始作妖,經常打一個字要卡半天,甚至可以看到電腦自動打字的尷尬場面。因此,我又重新下載回了手心輸入法。由於我手機上也是使用的同樣的輸入法,便想着可以利用輸入法帶的同步功能來進行個人詞庫的同步。然而,在實際使用的過程中,我發現手機端的登錄比較順暢,畢竟一直維護,而電腦端的情況則復雜得多。Windows 平台上的最后一次更新還是在 2018.10.18。打開登錄界面就會出現錯誤提示。
但是,手機上使用相同的賬號可以登錄,所以我判斷是電腦端在打開鑒權界面時發生了錯誤。
錯誤定位與初步調查
於是使用Fiddler進行抓包,果不其然,在抓取的請求列表中發現了與 openapi.360.cn
通信400的結果。
該應用訪問的URL是:
https://openapi.360.cn/oauth2/authorize?client_id=ae2a197a0f3a16cb5b088fbd51db155b&response_type=token&redirect_uri=xinshuru.com&scope=basic&display=desktop
openapi.360.cn
是360的應用開放平台,其官方文檔位於 這里。在文檔的2.1.2節可以看到,該 OAuth 2.0 接口需要一些參數。
請求參數:
參數名 | 必選 | 介紹 |
---|---|---|
client_id | True | 創建應用時獲得的App Key |
response_type | True | 此值固定為“code” |
redirect_uri | False | 授權后要回調的URI,即接收Authorization Code的URI, 其值可以是“oob”。 非“oob”值的redirect_uri所在域名必須與開發者注冊應用時所提供的回調地址的域名相匹配 |
scope | False | 以空格分隔的權限列表,若不傳遞此參數,代表請求默認的basic權限。(目前只有basic權限) |
state | False | 用於保持請求和回調的狀態,授權服務器在回調時(重定向用戶瀏覽器到“redirect_uri”時),會在Query Parameter中原樣回傳該參數 |
oauth_version | False | (可選)版本號,如果填寫必須為1.0 |
display | False | 登錄和授權頁面的展現樣式,360桌面應用請傳遞“desktop”,默認為“default”或空。 |
relogin | False | 僅在實現"使用360賬號登陸"功能時才需要傳遞。當瀏覽器有360cookie時,傳遞relogin可展示“當前賬號登陸確認頁”;relogin值請傳遞公司域名,如www.360.cn可傳遞"relogin=360.cn" |
我又直接使用瀏覽器打開了手心輸入法的授權URL,竟然可以直接打開,還很貼心地給出了錯誤提示:
查詢請求參數表格,可以發現 redirect_uri
不是一個必選參數,因此,我直接從 queryString 中刪去了該參數,此時,請求URL變成:
https://openapi.360.cn/oauth2/authorize?client_id=ae2a197a0f3a16cb5b088fbd51db155b&response_type=token&scope=basic&display=desktop
再次使用瀏覽器打開該鏈接,發現已經可以正常輸入賬號密碼進行登錄了:
於是,接下來的問題就是如何將客戶端的錯誤請求更改為修改后的正確請求。
問題解決
既然已經定位到了問題,而且找到了可行的方案,現在的問題就是如何攔截並修改輸入法客戶端發往服務端的請求。
剛好,我使用的抓包軟件 Fiddler 就可以設置自定義攔截規則。
打開自定義規則編輯器后,可以根據注釋發現其使用的是 JScript.NET 語言。關於該語言的資料可以在這里找到:JScript.NET Reference。
由於我們現在需要完成的事情是修改客戶端請求,於是,我們需要改寫自定義規則中關於請求的部分。使用 Fiddler ScriptEditor 菜單欄中的 Go
-to OnBeforeRequest
選項可以直接定位到與請求相關的方法位置。
在方法體的最后,我們加上自己對 openapi.360.cn
的攔截修改規則:
static function OnBeforeRequest(oSession: Session) {
// 如果你之前沒有使用過該功能,下面未注釋的代碼應該位於注釋了的代碼后面
/*
if (m_AlwaysFresh && (oSession.oRequest.headers.Exists("If-Modified-Since") || oSession.oRequest.headers.Exists("If-None-Match")))
{
oSession.utilCreateResponseAndBypassServer();
oSession.responseCode = 304;
oSession["ui-backcolor"] = "Lavender";
}
*/
if (oSession.HostnameIs("openapi.360.cn")) { // 只處理目標站點
var url = oSession.url; // 當前會話的 URL
var newUrl = url.Replace("redirect_uri=www.xinshuru.com&", String.Empty); // 刪去 URL 中 redirect_uri 部分
oSession.url = newUrl; // 替換 URL
}
}
之后,保存(Ctrl
+S
)該文件即可。如果操作正確,應該看到類似下圖的界面:
在打開 Fiddler 的情況下,再次打開手心輸入法的登錄頁面,可以看到已經正常打開:
此時輸入用戶名和密碼即可正常登錄,使用同步功能了。