接口安全問題java
爲開發者分配AccessKey(開發者標識,確保惟一)和SecretKey(用於接口加密,確保不易被窮舉,生成算法不易被猜想)。redis
參數簽名算法
請求攜帶參數AccessKey和Sign,只有擁有合法的身份AccessKey和正確的簽名Sign才能放行。這樣就解決了身份驗證和參數篡改問題,即便請求參數被劫持,因爲獲取不到SecretKey(僅做本地加密使用,不參與網絡傳輸),沒法僞造合法的請求。api
雖然解決了請求參數被篡改的隱患,可是還存在着重複使用請求參數僞造二次請求的隱患。數組
timestamp+nonce方案安全
nonce指惟一的隨機字符串,用來標識每一個被簽名的請求。經過爲每一個請求提供一個惟一的標識符,服務器可以防止請求被屢次使用(記錄全部用過的nonce以阻止它們被二次使用)。服務器
然而,對服務器來講永久存儲全部接收到的nonce的代價是很是大的。可使用timestamp來優化nonce的存儲。markdown
假設容許客戶端和服務端最多能存在15分鐘的時間差,同時追蹤記錄在服務端的nonce集合。當有新的請求進入時,首先檢查攜帶的timestamp是否在15分鐘內,如超出時間範圍,則拒絕,而後查詢攜帶的nonce,如存在已有集合,則拒絕。不然,記錄該nonce,並刪除集合內時間戳大於15分鐘的nonce(可使用redis的expire,新增nonce的同時設置它的超時失效時間爲15分鐘)。網絡
請求接口:api.test.com/test?name=h…dom
客戶端
服務端
在APP開放API接口的設計中,因爲大多數接口涉及到用戶的我的信息以及產品的敏感數據,因此要對這些接口進行身份驗證,爲了安全起見讓用戶暴露的明文密碼次數越少越好,然而客戶端與服務器的交互在請求之間是無狀態的,也就是說,當涉及到用戶狀態時,每次請求都要帶上身份驗證信息。
與上面開發平臺的驗證方式相似,爲客戶端分配AppKey(密鑰,用於接口加密,不參與傳輸),將AppKey和全部請求參數組合成源串,根據簽名算法生成簽名值,發送請求時將簽名值一塊兒發送給服務器驗證。
這樣,即便Token被劫持,對方不知道AppKey和簽名算法,就沒法僞造請求和篡改參數。再結合上述的重發攻擊解決方案,即便請求參數被劫持也沒法僞造二次重複請求。
登錄和退出請求
登錄和退出流程
客戶端
服務端
服務端流程