1. 程式人生 > >誰動了我的 Token

誰動了我的 Token

這裡涉及到的系統是一個 7 年的遺留系統(技術棧是 .NET MVC2),即將被客戶淘汰。這篇博文的主題無關技術本身,文中談到的技術細節也不是什麼高大上的,更多的是想記錄因這件事情觸發的非技術思考。

早上7點45分來到公司,我坐在辦公桌旁邊開始考慮今天的工作事項。想到客戶一直抱怨的電子表單系統在產品環境上8000多個無法重現的錯誤日誌就亞歷山大,“替換成微軟類庫也並不一定解決問題,客戶又在搗亂。今天一定要和夏夏一起看看這個問題,優先順序得提上來”,我心裡暗自的想著,並把它加到了待辦事項的第一條,優先順序標為高,截止時間是今天。

開了個好頭,但遭遇IE-Only問題

開完早會,我和夏夏瞭解了問題上下文,然後開始分析錯誤日誌。我倆驚訝的發現,其中7000多條錯誤日誌是發生在表單導航部分!夏夏說,“就先從它開始吧。” 我倆很快統一思路,瞄準這幾個頁面就開始搭建環境嘗試問題的復現。

按下遇到的各種環境問題不提,這個錯誤很快就在IE瀏覽器(文中統稱IE)上重現了,而且只在IE上才有這個問題:頁面缺少Anti-CSRF Token導致請求被拒絕。“哎,這不錯!”,夏夏用他一貫的幽默風格說道。我想:是的,好兆頭,萬事開頭難,我們似乎開了個好頭,然而這怎麼好像又是IE啊,真不靠譜。

更不靠譜的e.preventDefault?

時間已經轉眼到了10點半,我們開始嘗試定位程式碼,尋找問題的根源。咦,貌似看起來頁面前進後退的按鈕觸發了Form的POST請求,而服務端收到的請求中並沒有Token。那麼“我們頁面AntiCSRF Token是怎麼產生的呢?”我問夏夏,夏夏說:“嫻靜,你看這個js檔案”。

12345 form.submit(function(){if("AntiCSRF-TOKEN"element notexists){form.append
(input'AntiCSRF-TOKEN'with value)}});

“哦,橫切了一刀”,我說。夏夏說:“恩,你說的太對了!是在所有Form提交時自動追加Token”。我想這看起來沒問題,在早期系統中經常這樣幹。那麼是誰動了我的Token呢?

11點了,我們的診斷工作緊張而有序的繼續進行著,分析各種可能出現的異常路徑以及可能性。各種測試驗證貌似都沒有問題。“這不應該呀。夏夏,我們在裡面加上e.preventDefault,不讓它提交,手工測測看。”這時我開始亂入,懷著試試看的態度對夏夏說。心想,怎麼有些像回到了5年前工作在這個系統上的狀態。夏夏改了程式碼並編譯執行,奇怪的事情發生了:Form提交成功,並且錯誤被修復了!!不光開了個好頭,好像我們還中彩蛋了的感覺。

我和夏夏都驚呆了:“這怎麼可能?” 夏夏說。“是啊”,我說,“e.preventDefault不是應該阻止提交嗎?” 暗想我就是最近一段時間沒寫前端程式碼而已,世界變化這麼快?我和夏夏又過了一遍Anti-CSRF Token處理程式碼,做了各種嘗試,仍然沒有頭緒。即使e.preventDefault可以解決問題,但我們仍然不知道問題根源。誰動了我的Token!

又是IE實現的問題?

思維似乎有些短路了,我便建議:“我們來求助一下網路吧”。果然StackOverflow上發現了同樣的問題,IE上Form提交時丟失動態新增的欄位,不過是IE9版本。看完了推薦的答案很是吐血 — IE相容模式。熟悉IE的程式設計師都知道,這基本可以作為修復IE問題的萬能解藥。

夏夏說,“我們先來試一下”。修改程式碼執行系統,叮,問題也被修復了!天哪,IE啊~~~各種黑在我的心裡飄過,IE的瀏品又一次被拉低了(如果它有的話)。好吧,微軟的實現總是跟別人不一樣。於是我開始尋找各種微軟的文件、論壇,補丁網站,反饋網站,IE Google group試圖從裡面找到更多的討論和證據,然各種同樣的討論貼最後都指向了相容性這個文章,貌似,就是IE的問題。然而沒有找到明確的官方支援讓我們仍然不太確定。

同時,在這眾多的相似問題中還有一個現象引起了我們的注意:網路似乎只報了IE9的問題,而我們是IE9以上都有這個問題,似乎不太對”。我們繼續翻閱著程式碼進行各種嘗試,思路再次陷入了僵局。到底是誰動了我的Token!!

時間過的很快,已經晚上6點多了,解決方案是什麼?產品環境的問題怎麼辦?我和夏夏糾結著:“那要不就這樣,我們先用第二個方案把產品問題修了……”。是啊,需要趕緊修復產品環境的問題。然與此同時,沒能最終找到懸案的罪魁禍首讓我倆糾結萬千。

這說不通啊?

正好這時強哥揹著電腦包從外面走了進來,和他聊起了這個問題,強哥說:“這不大對啊”,經過一番討論,在夏夏離開去討論另一個問題的時候,強哥終於搶到了鍵盤。同樣的復現步驟和思路最終也得到了同樣的IE相容性的解決方案等等。“但這說不通啊?”強哥不斷的重複著這句話。心中不解的疑惑使得我們三個又重新加入了新一輪的分析中:“等等,好像這裡執行了兩次,第一次失敗,而第二次就成功了”,強哥敏銳的撲捉到了又一絲新的線索,事情好像有了新的轉機。

Form提交了兩次?

“我們再來抓一下包看看”,夏夏說。開啟Fiddler,重現問題。果不其然,同一個請求出現兩次,第一次失敗,第二次成功。問題轉移了:“為什麼會出現重複提交呢?” 時間一分一分的過去。已經晚上8點多了,我的肚子很餓,胃有些隱隱作疼。辦公室裡也只有少數一部分人了,沙沙幫我們找來了救命的小浣熊。這個時候,我們三個都不約而同的看到了下面這篇Stackoverflow的帖子:

強哥說,“這好像沒關係,他這程式碼寫的不對,Form上的按鈕是Submit型別,還繫結Click去提交。”夏夏說,“是的,程式碼問題。” 氣氛似乎有些緩和,強哥隨口說,“不會,我們就是這麼幹的吧?”

真相大白

突然,空氣好像被凝固了一般,夏夏和強哥對視x秒。強哥說,“要不咱查查程式碼”。夏夏說,“我也覺的得查查”。我說,“這怎麼可能? 這是基本知識好不好”。然後夏夏就真的開啟程式碼庫查了起來。幾分鐘後,只聽夏夏:“@#¥%%@#%&&”。 強哥也湊了過去,然後從椅子上“跳”了起來,我默默的在一旁畫圈圈,原來是你這廝動了我的Token!!!。

“啊!我也知道為什麼e.preventDefault能解決問題了”,我拍著桌子說道。夏夏和強哥互相看了一眼,哈哈大笑:“因為它幹掉了一次。”

問題的罪魁禍首就這樣找到了,我們通過Git提交歷史也知曉了這個問題是在n年前解決“按鈕多次點選問題”時引入的。然故事並沒有在此結束,找出罪魁禍首的興奮激動過後,帶給我們三個更多的是凝固的空氣和沉悶的心情。夏夏說,“這真是打臉。”是的,在這一點上沒什麼可矯情的。

你離真相其實只有一步之遙

在回家的地鐵上,我們三個臭皮匠仍然在交換那酸甜苦辣的各種複雜心情,反思和討論我們的工作以及白天錯過了什麼。這讓我記起了那個關於吃饃的故事:第一個、第二個、第三個、在吃第七個饃的時候飽了,並不意味著我們能抹殺前六個饃的功勞,只吃第七個饃就可以了。然現實的情況下很多人在第六個饃的時候就放棄了。我和夏夏在整個的過程中,就像警察找到了失蹤的物品和一隻替罪羊一樣,真正的罪犯並沒有被抓到。整個事情並不正常,甚至e.preventDefault的行為都很詭異。事出反常必有妖,而最終的我們不管怎樣其實選擇的都是放棄。

如果重來?

科學需要的是嚴謹、懷疑和批判的態度,軟體工程也是一樣。在問題面前,我們需要嚴謹的態度並拋棄既有的偏見,抽繭剝絲,不放過一絲的線索直到找到那個動了我們程式碼的爬蟲。 “IE總有各種稀奇古怪的問題,出問題也是它自己的問題,要不其他瀏覽器為啥沒問題?”帶了這樣的有色眼鏡去解決問題,會遮擋住我們敏銳的眼睛,誤入歧途。也許我們並沒有真正在解決問題,只是在給自己的偏見找到一個藉口而已。

只有這些嗎?

我們常說作為ThoughtWorks作為一家服務公司要具備專業化的服務精神,工作中要具有專業精神,然什麼是專業化?我們常說作為技術是ThoughtWorks的核心競爭力,我們要追求技術卓越,然什麼是卓越?這次事件給我上了深刻的一課。

我想,在交付壓力面前,在客戶挑戰面前,我們對於問題的響應度和處理方式反映了我們的專業度有多少。

  • 當我們修復一個產品問題的時候,是不是把這個問題解決了就結束了?
  • 當我們無法解決一個產品問題的時候,是不是將問題拋給客戶,“我加了點日誌過兩天再看看”,就結束了?
  • 當我們無法解決一個第三方技術問題的時候,是不是一個簡單的“要升級”就結束了呢?

當交付壓力一次次被當做不能技術卓越的擋箭牌,當面對各種無奈與挑戰的時候,是不是經常說“算了,就這樣吧”。那你有沒有發現,悄然間我們的專業化服務底線一次次的被觸碰。與此同時,我們技術前進的步伐也已經悄悄的停了下來。

三指規則:當你用一個手指指向別人時,注意另外三個手指所指向的方向。—溫格伯

我們那些還可以做得更好?我們的客戶面臨什麼樣的問題?我們還能做些什麼來幫助他們解決這些問題?如果讓我只選擇一個品質來提升我們的專業服務精神,那就是“死磕到底”。

死磕到底

死磕是什麼?普通話就是“較勁兒”、“不達目的不罷休”的意思。

死磕就如凌晨四點洛杉磯的科比,就如他成名後依然每天完成800個投籃的高強度訓練以保持專業的水準。

死磕就如邏輯思維羅振宇每天堅持6:30左右發60秒語音,每週的優酷視訊。

死磕就如這次事件中的強哥,一次次從問題中找到線索找到根源。

試想一下如果沒有強哥的加入,真相可能就會被淹沒。他們所展現的是與常人所不同的專業精神和匠人精神,而這種精神是為客戶創造價值的根本!

寫在最後

當面包成為習慣的時候,甚至有時會有夾心的時候,當抱怨成為習慣,當環境變得越來越舒適的時候,會讓人忘記初心,喪失競爭和生存的動力。“Stay Hungry,Stay Foolish” 與諸君共享。