android 常用api 接口簽名驗證

從登錄注冊說起該驗證的全部過程:

1.android 登錄時一般是這樣:
loginData.put("name", userNameText.toString());
loginData.put("password", passWordText.toString());
loginData.put("platform", "android");
//同步方式
try {
    //調(diào)用登錄接口網(wǎng)絡(luò)請求
    JSONObject response = okHttpManager.post(login_url, loginData);
2.在客戶端在登錄成功時 記錄 以下信息
//保存用戶信息, 常用的單獨保存
PreferenceManager pm = PreferenceManager.getInstance();
pm.setString("user_id", loginDetail.getString("user_id"));
pm.setString("app_token", loginDetail.getString("app_token"));
pm.setString("app_ticket", loginDetail.getString("ticket"));
pm.setString("userinfo", loginDetail.toString());

那服務(wù)器端返回的app_token 以及ticket 是怎么產(chǎn)生的呢 有什么作用呢羹应?????

3.服務(wù)器端 接收到登錄信息后應(yīng)該是這樣處理:
//生成token
$app_token  = empty($userInfo['app_token']) ? $this->genAppToken($retParams['name'], $retParams['platform']) : '';

這個時候?qū)⒏聈sers表 的 app_token字段加派。

//生成ticket
$ticket = $this->genAppToken($userInfo['user_id'], $userInfo['mobile']);

這個時候判斷check_online表 有沒有該條數(shù)據(jù)鱼冀,如果沒有將其插入到online_user表中,該表的設(shè)計應(yīng)該是這樣:

id user_id ticket expire_time platform

(這個表的作用是記錄成功登錄 也就是正在線上的表鞠抑,如果登出的話就應(yīng)該將這條記錄刪除)

并將(userid跟ticket)做索引
(所以判斷用戶是否在線 可以通過user_id 或者通過ticket 做判斷)

這個genAppToken 可以用md5 或者sha 都行,反正就是單向加密的都可以,這個時候可以進行api 接口簽名驗證工作

客戶端邏輯跟服務(wù)器端邏輯相似

服務(wù)器端如下:

api的話需要區(qū)分是否需要登錄的接口 所以這塊需要做到免驗證判斷:如下可以實現(xiàn)

$loginArr  = array('login', 'register', 'mobile_verifycode_login', 'forget_password', 'send_email', 'createSMS', 'check_exis    ts', 'notifySync', 'wx_auth_register','wx_auth_login');
 60             if (!in_array($method, $loginArr)) {
 61                 $this->load->model(array('User_model'));
 62                 $operator      = $this->isLogin();
 63                 $this->operator = array(
 64                     'user_id' => (int)$operator['user_id'], 'ticket' => $operator['ticket']
 65                 );
 66             }

簡單的對數(shù)組進行添加就可以實現(xiàn)添加免驗證的接口仆百,根據(jù)上面做的online_user表的工作绽淘,很顯然能知道 判斷一個用戶是否已經(jīng)登陸 只要根據(jù)他的user_id 或者ticket就能夠判斷,如果不在線 則跳到登錄頁

在免接口驗證中测萎,顯然不能通過ticket 來進行對用戶的區(qū)分亡电,所以我們用了sign簽名的方式來解決API簽名的一些問題

  • 請求參數(shù)是否被篡改
  • 請求來源是否合法
  • 請求是否具有唯一性

所以加簽策略可以如下所示:

$sign  = $params['sign'];
269         $timestamp  = $params['fx_timestamp'];
270         $secret = “123sqweqweq“;    //換成自己的secret
271


272         $app_ticket = $this->input->get_post(COOKIE_TICKET);
273         $app_token  = '';
274         if (!empty($app_ticket)) {
275             //獲取app_token
276             $cacheData  = $this->ciredis->hGetAll('online:ticket:' . $app_ticket);
277             $userInfo  = $this->User_model->get(array('user_id' => $cacheData['user_id']));
278             $app_token = !empty($userInfo['app_token']) ? $userInfo['app_token'] : APPSECRET;
279         }

客戶端往服務(wù)器端傳參數(shù)的時候,對其是否傳app_ticket 做判斷硅瞧,如果有 則用這個app_ticket 對表或者緩存中去app_token (要注意 app_ticket 跟app_token不能放在一個緩存或一個表中份乒,還是需要user_id做關(guān)聯(lián))

//過濾掉sign
285         unset($params['sign'], $params['s']);
286         //排序
287         ksort($params);
288         reset($params);
289
290         //拼接字符串
291         $arg = "";
292         while (list ($key, $val) = each($params)) {
293             $arg .= $key . "=" . $val . "&";
294         }
295         $arg    = rtrim($arg,'&');

先保存起來用戶傳遞的簽名,需要服務(wù)器端用自己的方法生成簽名腕唧,然后跟客戶端傳來的簽名做匹配或辖,如果成功就通過,否則就報簽名錯誤

一般服務(wù)器端驗證簽名步驟都是這樣:

1.先排序ksort

2.拼接字符串 foreach($params as $key=>$val) {
$arg .= $key.”=“.$val.”&”;
}

3.然后對拼接完的字符串再加一段隨機數(shù)進行md5 或者 sha 加簽,類似如下:

key = “123aqwqw”;
$newSign = sha1($arg.”$key”);

這個時候得到的newSign 就是服務(wù)器所生成的sign(當(dāng)然其中的加簽字符串可以設(shè)置長些復(fù)雜些);
那這個newSign 跟客戶端傳過來的sign 做匹配 枣接。相同則通過颂暇。

這樣做的好處如下:

newSign 是根據(jù)所傳遞的參數(shù)進行加密的 所以 當(dāng)其他人更改參數(shù)的時候,服務(wù)器端產(chǎn)生的newSign 必定與客戶端傳遞的sign 不同月腋,簽名則不匹配
這個時候 就會有人問 ==如果我劫持了客戶端的代碼 同時獲取了客戶端的加簽程序蟀架,不就可以更改客戶端的sign了嗎。==

是這樣的榆骚,所以android 經(jīng)常使==用jni 用c寫一套加簽的流程==片拍,這塊代碼是反編譯不能獲取不到的(==這塊代碼是編譯到so 文件中的==),所以保證了客戶端的代碼安全

客戶端代碼如下:

secret  = PreferenceManager.getInstance().getString("app_token");
ShowLog.e(url);
addTicketToParams(params);
buildSign(params);

在網(wǎng)絡(luò)請求的地方進行加ticket 加 sign(網(wǎng)絡(luò)請求這塊必須要做成==公共調(diào)用==妓肢,這樣才能實現(xiàn)對接口訪問的統(tǒng)一捌省,可以做成單例模式。)

secret 作用是獲取登錄那會保存的app_token,
addTicketToParams 用來對params 進行加入ticket 碉钠,這個ticket 也是使用登錄保存的ticket

重點在==buidlSign==這個部分纲缓。

params.put("timestamp", Long.toString(timestamp));
params.put("appsecret", secret);

Map<String, String> sortedParams        = new TreeMap<String, String>(params);
Set<Map.Entry<String, String>> entries  = sortedParams.entrySet();

StringBuffer buffer = new StringBuffer();
byte[] bytes    = null;
try {
    for (Map.Entry<String, String> entry : entries) {
        if (buffer.length() > 0) {
            buffer.append("&");
        }

        buffer.append(entry.getKey()).append("=").append(entry.getValue());

獲取時間戳以及獲取之前的secret 也就是app_token
然后也跟服務(wù)器端一樣 遍歷并挨個加=以及& 然后這時候加入jni 的編寫的c語言程序加參
跟服務(wù)器端邏輯類似 只是用c 來實現(xiàn)服務(wù)器端php語言的實現(xiàn)效果
這個時候會返回一個字符串sign,然后

arams.remove("appsecret");
ShowLog.e(params.toString());
params.put("sign", doencrypt(buffer.toString()));
ShowLog.e(params.get("sign"));

將這個字符串加入sign 并與服務(wù)器端交互

這就是整個API接口簽名驗證的整個過程喊废。

這塊要注意的點在于不管是需要驗證還是免驗證的接口 必須讓app_ticket 以及app_token 成對出現(xiàn)(要么都有 要么都沒有)
文章出處:https://www.ci92.com/Index/Blog/detail?id=17

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末祝高,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子污筷,更是在濱河造成了極大的恐慌工闺,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓣蛀,死亡現(xiàn)場離奇詭異陆蟆,居然都是意外死亡,警方通過查閱死者的電腦和手機惋增,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門叠殷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诈皿,你說我怎么就攤上這事林束。” “怎么了稽亏?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵诊县,是天一觀的道長。 經(jīng)常有香客問我措左,道長依痊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任怎披,我火速辦了婚禮胸嘁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凉逛。我一直安慰自己性宏,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布状飞。 她就那樣靜靜地躺著毫胜,像睡著了一般书斜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酵使,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天荐吉,我揣著相機與錄音,去河邊找鬼口渔。 笑死样屠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缺脉。 我是一名探鬼主播痪欲,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼攻礼!你這毒婦竟也來了业踢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤礁扮,失蹤者是張志新(化名)和其女友劉穎陨亡,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體深员,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡负蠕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了倦畅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遮糖。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖叠赐,靈堂內(nèi)的尸體忽然破棺而出欲账,到底是詐尸還是另有隱情,我是刑警寧澤芭概,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布赛不,位于F島的核電站,受9級特大地震影響罢洲,放射性物質(zhì)發(fā)生泄漏踢故。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一惹苗、第九天 我趴在偏房一處隱蔽的房頂上張望殿较。 院中可真熱鬧,春花似錦桩蓉、人聲如沸淋纲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洽瞬。三九已至本涕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伙窃,已是汗流浹背菩颖。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留对供,地道東北人位他。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓氛濒,卻偏偏與公主長得像产场,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子舞竿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容