//根據請求型別拼接引數

NameValueCollection form = HttpContext.Current.Request.QueryString;

string data = string.Empty;

switch (method)

{

case "POST":

Stream stream = HttpContext.Current.Request.InputStream;

string responseJson = string.Empty;

StreamReader streamReader = new StreamReader(stream);

data = streamReader.ReadToEnd();

break;

case "GET":

//第一步:取出所有get引數

IDictionary<string, string> parameters = new Dictionary<string, string>();

for (int f = 0; f < form.Count; f++)

{

string key = form.Keys[f];

parameters.Add(key, form[key]);

}

// 第二步:把字典按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))

{

query.Append(key).Append(value);

}

}

data = query.ToString();

break;

default:

resultMsg = new ResultMsg();

resultMsg.StatusCode = (int)StatusCodeEnum.HttpMehtodError;

resultMsg.Info = StatusCodeEnum.HttpMehtodError.GetEnumText();

resultMsg.Data = "";

actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

base.OnActionExecuting(actionContext);

return;

}

bool result = SignExtension.Validate(timestamp, nonce, id, signtoken,data, signature);

if (!result)

{

resultMsg = new ResultMsg();

resultMsg.StatusCode = (int)StatusCodeEnum.HttpRequestError;

resultMsg.Info = StatusCodeEnum.HttpRequestError.GetEnumText();

resultMsg.Data = "";

actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

base.OnActionExecuting(actionContext);

return;

}

else

{

base.OnActionExecuting(actionContext);

}

}

public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)

{

base.OnActionExecuted(actionExecutedContext);

}

}

然後我們進行測試,檢驗api請求的合法性

Get請求:

1.獲取產品資料,傳遞引數id=1,name="wahaha"  ,完整請求為http://localhost:14826/api/product/getproduct?id=1&name=wahaha

2.請求頭新增timespan,staffid,nonce,signature欄位

3.如圖當data裡面的值為id1namewahaha的時候請求頭中的signature和伺服器端計算出來的result的值是完全一樣的,當我將data修改為id1namewahaha1之後,伺服器端計算出來的簽名result和請求頭中提交的signature就不相同了,就表示為不合法的請求了

4.不合法的請求就會被識別為請求引數已被修改

合法的請求則會返回對應的商品資訊

post請求:

1.post物件序列化為json字串後提交到後臺,後臺返回相應產品資訊

2.後臺獲取請求的引數資訊

3.判斷簽名是否成功,第一次請求籤名引數signature和伺服器端計算result完全相同, 然後當把請求引數中count的數量從10改成100之後伺服器端計算的result和請求籤名引數signature不同,所以請求不合法,是非法請求,同理如果其他任何引數被修改最後計算的結果都會和簽名引數不同,請求同樣識別為不合法請求

總結:

通過上面的案例,我們可以看出,安全的關鍵在於參與簽名的TOKEN,整個過程中TOKEN是不參與通訊的,所以只要保證TOKEN不洩露,請求就不會被偽造。

然後我們通過timestamp時間戳用來驗證請求是否過期,這樣就算被人拿走完整的請求連結也是無效的。

Sign簽名的方式能夠在一定程度上防止資訊被篡改和偽造,保障通訊的安全

原始碼地址:https://github.com/13138899620/TokenSign