1.前言算法
分享一個的我最近完成的開放平臺設計數據庫
2.簡介緩存
開放平臺(如下簡API) 是爲供應商和分銷商(如下簡稱開發人員)開放的API 接口,開發人員能夠經過調用搜物API接口,快速的實現和搜物網的數據交換。搜物API支持Json 格式和XML數據格式進行數據交換,搜物API 根據你傳入的數據格式返回對應的數據,如你傳入的是是XML搜物API將返回Xml 格式數據如是Json 則返回Json格式數據安全
3.整體架構架構
如上圖所示,這裏採用了分層來的思想開發本系統ui
l HelperLogic 助手類加密
l CahceLogic 緩存部分靜態數據,spa
l DataLogic 數據庫業務層設計
l OrderLogic 訂單邏輯層3d
l ProductLogic 產品邏輯層
l purviewLogic 鑑權邏輯層
l LogisticsLogic 物流模板邏輯層
4.業務邏輯處理
5.簽名算法
/// <summary> /// 獲取簽名字符串 /// </summary> /// <param name="parameters">全部字符型的請求參數</param> /// <param name="secret">簽名密鑰(即搜物APIKey)</param> /// <returns>簽名</returns> public static string GetSignatureStr(IDictionary<string, string> parameters, string secret) { parameters.Remove("Signature"); // 第一步:把字典按Key的字母順序排序 IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters); IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator(); // 第二步:把全部參數名和參數值串在一塊兒 StringBuilder query = new StringBuilder(); while (dem.MoveNext()) { string key = dem.Current.Key; string value = dem.Current.Value; if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value)) { query.Append(key + "=" + value + "&"); } } query.Append("key=" + secret); // 第三步:使用MD5加密 MD5 md5 = MD5.Create(); byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString())); // 第四步:把二進制轉化爲大寫的十六進制 StringBuilder result = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) { string hex = bytes[i].ToString("X"); if (hex.Length == 1) { result.Append("0"); } result.Append(hex); } return result.ToString(); }
6.安全性考慮
1.權限接口控制
2.異常訪問
1.在30分鐘內,10次簽名出錯,認爲帳號異常
2.訪問過於頻繁
3.手動添加黑名單
3.用戶可追溯性
咱們主要實現2點功能 1. 記錄用戶的訪問操做,好比訪問那些接口,上傳了那些數據, 2.對於重要的數據的可追溯性,如商品價格,庫存等 3. 記錄每一個請求耗時多久 爲了實現以上3點功能,咱們在這裏引入log4net 作爲日誌系統,減小開發工做量
7.POST 數據和返回數據格式參考
[XmlRoot(ElementName = "DataPost")] public class DataPostCommon { /// <summary> /// 方法名 /// </summary> [XmlElement(ElementName = "MethodsName")] public string MethodsName { get; set; } /// <summary> /// ApiGuid /// </summary> [XmlElement(ElementName = "ApiGuid")] public string ApiGuid { get; set; } /// <summary> /// 數據簽名 /// </summary> [XmlElement(ElementName = "Signature")] public string Signature { get; set; } } [XmlRoot(ElementName = "DataPost")] /// <summary> /// 用戶Post 數據格式 /// </summary> public class DataPost<T> : DataPostCommon { [XmlElement(ElementName = "Parameters")] public T Parameters { get; set; } }
/// <summary> /// 服務返回 /// </summary> [XmlRoot(ElementName = "SeverReturn")] public class SeverReturn<T> { public SeverReturn() { ErrNo = ErrorNo.IsSuccess; } /// <summary> /// 錯誤代碼 /// </summary> [XmlElement(ElementName = "ErrNo")] public int ErrNo { get; set; } /// <summary> /// 錯誤描述 /// </summary> [XmlElement(ElementName = "ErrorDesc")] public string ErrorDesc { get; set; } [XmlElement(ElementName = "RunResults")] public T RunResults { get; set; } } }