防重提交設計實戰

為什麼需要防範重複提交呢?舉個最直接的栗子:你在商城裡買了7888元的iphone x,付款後頁面卡頓導致你重複點擊了付款按鈕,這時候如果後端不加重複交易驗證的話,相當於付款15766元買了Iphone x手機,划算吧?

不單是互金系統交易時會生產此問題,凡涉及表單提交都會遇到,這裡以某互金系統為例說明交易防重的過程設計。下圖是交易防重設計的示圖:

防重提交設計實戰
這個過程相信大家都不陌生,生活中隨處可見。開封菜的甜品站,先付款,再給小票,拿著小票到取餐口拿甜品,交易完成後,小票撕毀。這就是一個典型的防止重複取餐的例子。

回到上圖,來深入瞭解一下這個過程:

  • 1、在進入到需要防重交易的表單頁面之前,請求後端生成token的服務,生成token並存儲在後端,與該用戶的請求綁定,便於後期在交易驗證時與之比對,token返回到交易頁面。
  • 2、攜帶token提交表單,在進入真正交易之前,做token驗證(比如使用AOP),如果存在,則token正常,比對成功後銷燬進入正常的交易功能。如果不存在,則證明token已經被銷燬,為重複提交請求。

以上步驟可以看出token的關鍵性,若token獲取失敗,那麼交易將無法完成,所以需要保證token服務的高可用性。

以上過程針對一個交易是完全沒有問題的,但若涉及兩個以上的關鍵交易提交時,就會出現後請求的交易獲取的token替換首次交易獲取的token,那麼在首次交易提交時,會出現token找不到的情況,導致交易失敗。由此引出另外兩個關鍵的問題點:

token的數量以及token的銷燬機制。 數量決定了能同時發起交易的數量,所以token的數量最好能夠覆蓋所有關鍵交易同時發起來的數量。token的銷燬決定了使用token的正常順序。

基於上面流程,我們再改造一下生成token的模塊。

防重提交設計實戰

關鍵示例代碼:

防重提交設計實戰

生成token方法

防重提交設計實戰
防重提交設計實戰

交易校驗,主要由攔截器完成。

防重提交設計實戰

一般的解決方案是在前端由JS控制提交表單按鈕,提交後置灰,禁止第二次提交。但此方法也只針對小白用戶有效,防範機制也不是很徹底,比如直接調用請求而非通過頁面表單進行,比如JS校驗代碼清除等,可以繞過JS的置灰功能進行二次提交。

採用前端JS置灰防止重複提交請求,再加上後端token驗證,可以更有效的防止關鍵交易的重複提交。

防重提交設計實戰

原文發表於:wp號 歪脖貳點零


分享到:


相關文章: