WebApi與手機客戶端通訊安全機制

2022-04-11 23:37:01 字數 3133 閱讀 6698

最近公司有幾個專案需要開發手機客戶端,伺服器端選用webapi,那麼如何保證手機客戶端在請求伺服器端時資料不被篡改,如何保證乙個http請求的失效機制,下面總結一下我們在專案中針對這兩個問題的解決方案。

基本思路如下:

具體實現如下(客戶端的實現,手機客戶端生成下面兩個引數的思路是一樣的):

1、ts時間戳

ts引數可以保證請求的時效性,在手機客戶端生成的ts,在伺服器端驗證一下,保證請求是在我們規定的時間段內,具體**如下:

(1)、生成ts(c#)**如下,andriod和ios可以同理生成

/// /// 獲取十位的時間戳

///

///

///

public string generatetimestamp(datetime dt)

(2)、伺服器端端驗證ts**如下,我們規定從手機客戶端發到伺服器端的請求有效期為5分鐘,時間戳引數是跟在http請求頭中

//獲取請求頭資訊

//10位時間戳

var ts = requestheader.get("ts");

//驗證ts是否合法(請求時間有效時間為:加減5分鐘)

var ts = ts;//10位時間戳

if (ts.length != 10)

var tsdate = comhelper.convertintdatetime(ts.tostring());

if (tsdate > datetime.now.addminutes(5) || tsdate < datetime.now.addminutes(-5))

(3)、comhelper公共類**如下

comhelper

2、sign簽名

(1)、sign的生成規則:伺服器端介面中的所有引數+uid+ts,去除掉引數中值為空的引數後, 按照引數key值排序,用&鏈結,並全部轉化為小寫,然後用md5加密,通過httpheader傳送到伺服器端介面。

生成sign大**如下(c#),android和ios可以同理生成

假如手機客戶端請求的乙個api介面為:

sign=md5(carid=2&cityid=3&key=222&statusid=1&ts=0123456789&uid=110)

(2)、驗證客戶端的sign,防止引數被修改

//請求簽名,客戶端生成的簽名

var sign = requestheader.get("sign");

//排序字典,按照key排序

sorteddictionarypostvalue = null;

//獲取請求中所有的引數

postvalue = comhelper.getrequestsortdic(true);

postvalue.add("uid", uid);//api賬戶名稱

postvalue.add("ts", ts);//10位時間戳

string apiprivatekey = "2d7e7c96-dac5-4526-96c3-c60cdec4b120";//客戶端和手機端保持一致

//伺服器端生成的sign

string mysign = comhelper.getresponsemysign(postvalue, apiprivatekey);

if (!sign.equals(mysign, stringcomparison.invariantcultureignorecase))

3、模擬測試

(1)c#模擬http請求,**如下

//請求的api位址

//生成ts

string ts = comhelper.generatetimestamp(datetime.now);

//sorteddictionary會自動按照key值排序

sorteddictionarysortdic = new sorteddictionary();

sortdic.add("statusid", "1");

sortdic.add("carid", "2");

sortdic.add("cityid", "3");

sortdic.add("name", "");

sortdic.add("key", "1233");

sortdic.add("uid","110");

sortdic.add("ts", ts);

string apiprivatekey = "2d7e7c96-dac5-4526-96c3-c60cdec4b120";//客戶端和手機端保持一致,md5加密多使用了乙個引數

//獲取sign簽名

string sign = comhelper.getresponsemysign(sortdic, apiprivatekey);

//傳送請求

system.net.webrequest wreq = system.net.webrequest.create(url);

wreq.headers.add("uid", "110");

wreq.headers.add("ts", ts);

wreq.headers.add("sign", sign);

system.net.webresponse wresp = wreq.getresponse();

system.io.stream respstream = wresp.getresponsestream();

using (system.io.streamreader reader = new system.io.streamreader(respstream, encoding.utf8))

(2)伺服器端驗證引數,引數驗證寫在baseapicontroller.cs檔案中,只要繼承該類的都可以驗證客戶端傳過來的引數

public class valuescontroller : baseapicontroller;}

安卓客戶端與PHP後台通訊

安卓端通過http協議的post方式訪問伺服器php後台,並傳送資料過來,資料格式是key1 value1 key2 value2 的形式,安卓端 形式 public static string dopost string url,map string,string params 設定http po...

TCP通訊,多客戶端通訊(客戶端 服務端)

客戶端和伺服器間的交流,客戶端傳送資訊,伺服器接收到,並返回資訊 長連線建立socket連線服務端 指定ip位址,埠號 通過ip位址找對應的伺服器 呼叫socket的getinputstream 和getoutputstream 方法獲取和服務端相連的io流 輸入流可以讀取服務端輸出流寫出的資料 輸...

webapi獲取請求客戶端位址

獲取客戶端ip位址 無視 若失敗則返回回送位址 public static string gethostaddress if string.isnullorempty userhostaddress 最後判斷獲取是否成功,並檢查ip位址的格式 檢查其格式非常重要 if string.isnullor...