1. 程式人生 > >webapi token、參數簽名是如何生成的(轉載)

webapi token、參數簽名是如何生成的(轉載)

就是 blog webapi rod 空值 VC acc base cut

API接口保障安全性原則:1.有調用者身份2.請求的唯一性3.請求的參數不能被篡改4.請求的有效時間

在剛接觸接口開發時,可能腦子裏壓根就沒有這個接口調用安全性的原則,但常識性的經驗告訴我們,每一個請求都應該有原則地保障安全性。

例如這個接口 http://127.0.0.1/api/user/list?type=value 這個獲取用戶列表信息的請求總不能在地址欄一輸入就直接顯示信息(雖然有點誇張,不至於阿貓阿狗的信息這麽容易get吧),在寫webapi接口原則性的基本要求必須得保證數據的安全性和請求的有效性

在這裏我就使用Token+參數簽名+時間戳 這三個系統參數來辦證請求的有效性(即時100%請求有效,也不能說100%也安全了)。

參數名 必選 類型 作用
token string 調用方標識,保障其身份是來自本系統認證過的,有效識別用戶身份
sign string 接口參數的key,value的記錄,防止參數值被篡改,防止偽裝請求
timestamp int 時間戳,防止重放攻擊

那麽問題來

1.token 如何生成?作用是什麽?

2.參數簽名如何生成?作用是什麽?

3.時間戳的作用是什麽?

看了這篇文章你就知道了。這三個系統參數是如何保證請求的有效性,一定程度上提高數據的安全性

1.token如何生成的?作用是什麽?

token生成:一般的api基本上主要分為兩種客戶端訪問api的token和需要用戶登錄之後的token,這裏我就來說一下後者,(簡單通俗做法)用戶登錄輸入用戶名、密碼,訪問api,驗證數據庫成功。這個時候可以產生token,失敗直接返回。問題又來了! 1.token生成的方式是什麽?2.token存在哪裏?3.token如何驗證是否正確 在驗證數據成功之後可以獲取唯一用戶標識(用戶名也行),就以username:zhanglin為例吧,對這個標識進行加密(des,MD5、其他的也行,關鍵數據必須得加密),這個加密之後的字符串就可以做為一個Token了。 2.token每次請求都需要進行傳遞,推薦存在cookie,也可以持久化到客戶端。現在有這樣一個api接口http://127.0.0.1/api/user/list?token=encryptUsernameStr 這個encryptZhanglinStr就是登錄成功後加密的username返回的給客戶端,客戶端用什麽保存這裏就不多介紹了,只需要知道返回給客戶端一個用戶訪問的Token類即可,到了服務器端方法驗證的時候再進行解密,獲取到字符串zhanglin,然後將這個zhanglin與系統用戶(可采用緩存數據庫、緩存token的值)對比,如果對比存在,則說明有權限去訪問api,反之非法的請求。 還是代碼來實現一下吧。代碼比較容易理解,就是為了把這個原理說清楚一點 [csharp]
view plain copy
  1. [Route("login")]
  2. public bool login(string account, string pwd)
  3. {
  4. var obj = Db.dbUsers.FirstOrDefault(f => f.Account == account && f.Pwd == pwd);
  5. if (obj != null)
  6. {
  7. string token = account.DESEncrypt(desKey);//加密產生token,
  8. HttpCookie cookie = new HttpCookie(cookieToken,token);
  9. HttpContext.Current.Response.Cookies.Add(cookie);//保存cookie
  10. return true;
  11. }
  12. else
  13. {
  14. return false;
  15. }
  16. }
token的產生就是登陸之後根據用戶標識保存在cookie裏,這樣在客戶端每次發送請求的時候都會帶上token這個參數,如下: [csharp] view plain copy
  1. [Route("list"), HttpGet]
  2. public List<string> List(string type,string token)
  3. {
  4. var obj = Db.dbUsers.FirstOrDefault(p => p.Account == token.DESDecrypt(desKey));
  5. //驗證token
  6. if (obj != null)
  7. {
  8. //返回數據集
  9. }
  10. else
  11. {
  12. //非法請求
  13. }
  14. }
3.這樣就可以驗證token是否正確,一般都是用緩存。 Token的作用的就是判斷請求是否是系統用戶發出的,這樣能有效識別請求用戶的身份信息 2..參數簽名如何生成?作用是什麽? 參數簽名sign:為了提高傳參過程中,防止參數被惡意修改,在請求接口的時候加上sign可以有效防止參數被篡改,那麽sign是如何起作用的呢? 看看它的生成方法就明白了 比如有這樣一個接口http:127.0.0.1/api/product?&type=zl&p1=value1&p2=value2&p3=&sign=signValue 第一步:拼接參數字符串,除去sign參數本身和為空值的p3,那麽剩下的就是字符串type=zl&p1=value1&p2=value2,然後按參數名字符升(降)序,得到字符串 p1=value1&p2=value2&type=zl 第二步:然後做參數名和值的拼接,得到字符串p1value1p2value2type=zl,註意編碼,不能出現這種&quot; ,要轉碼後“後拼接 第三步:將字符串進行DES加密,假設p1value1p2value2type=zl進行des加密後的結果是abc123,最終得到的字符串abc123就是參數sign的值signValue 第四步:在接口中我們會接收到參數名sign的參數值abc123,然後解密得到字符串p1value1p2value2type=zl,再與接口中參數拼接排序後進行比較,如果不一樣則說明參數的循序不一樣,參數的值就一定是被修改過了。 總結: 1.接口的調用方和接口的提供方統一約定參數加密算法 2.參數簽名就是對參數key ,value的一個記錄。參數如果被修改肯定對不上參數簽名,就不會調用請求 3.時間戳的作用? 在api請求的接口,客戶端請求的發生時間便是時間戳,這個參數到了服務器,與服務器端時間對比,如果時間間隔較長則無效。 在asp.net mvc的開發webapi接口時,可以使用mvc的過濾器進行以上三個關鍵參數的攔截過濾。以下代碼是在.net core中實現的,方法還是一樣的,都是在進入方法前進行攔截,這是一個登錄的api。 返回api結果是一個類ApiResult.cs,序列化成json對象,該類包含兩個泛型方法請求成功的Ok方法,請求失敗的Error方法 [csharp] view plain copy
  1. public class MyFilterAttribute : Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute
  2. {
  3. public override void OnActionExecuting(ActionExecutingContext context)
  4. {
  5. var request_param = context.ActionArguments.Values;
  6. var queryCollection = context.HttpContext.Request.Query;
  7. string account = string.Empty;
  8. string password = string.Empty;
  9. long timespan = 0;
  10. string signature = string.Empty;
  11. try
  12. {
  13. account = queryCollection.Where(p => p.Key == "account").Select(f => f.Value).FirstOrDefault().ToString();
  14. password = queryCollection.Where(p => p.Key == "password").Select(f => f.Value).FirstOrDefault().ToString();
  15. timespan = long.Parse(queryCollection.Where(p => p.Key == "timespan").Select(f => f.Value).FirstOrDefault().ToString());
  16. signature = queryCollection.Where(p => p.Key == "signature").Select(f => f.Value).FirstOrDefault().ToString();
  17. }
  18. catch (Exception ex)
  19. {
  20. var apiresult = ApiResult<bool>.Error("參數異常"+ex.ToString());
  21. context.Result = new JsonResult(apiresult);
  22. }
  23. //var accountName = context.RouteData.Values["accountName"].ToString()
  24. var expires_minute = (timespan - DateTime.Now.Ticks) / 60000000000;
  25. if (expires_minute> 10||expires_minute<-10)
  26. {
  27. var apimodel = ApiResult<bool>.Error("請求超時"+expires_minute);
  28. //var json = JsonConvert.SerializeObject(apimodel);
  29. JsonResult ret = new JsonResult(apimodel);
  30. context.Result =ret;
  31. }
  32. var ok = ("account" + account + "password" + password).Contains(signature);//ToDO 加密解密
  33. if (ok == false)
  34. {
  35. var apimodel = ApiResult<bool>.Error("非法請求");
  36. var json = JsonConvert.SerializeObject(apimodel);
  37. JsonResult ret = new JsonResult(apimodel);
  38. context.Result = ret;
  39. }
  40. base.OnActionExecuting(context);
  41. }
  42. }

作者:張林
原文標題: webapi token、參數簽名是如何生成的
原文鏈接:http://blog.csdn.net/kebi007/article/details/72861532

webapi token、參數簽名是如何生成的(轉載)