W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
正如我們核心思想DI里面所說的,我們把后臺很多功能資源都稱為服務(wù),所以在PhalApi框架中我們已經(jīng)系統(tǒng)規(guī)定了DI()->filter為過濾器服務(wù),以實(shí)現(xiàn)接口請求時(shí)的一些攔截操作,一如現(xiàn)在要說明的簽名驗(yàn)證。
在接口進(jìn)行初始化時(shí),會自動調(diào)用已注冊的過濾器服務(wù) DI()->filter ,關(guān)鍵的代碼如下:
//$vim ./PhalApi/PhalApi/Api.php
public function init()
{
$this->createMemberValue();
$this->filterCheck();
$this->checkStatus();
}
protected function filterCheck()
{
$filter = DI()->filter;
if (isset($filter)) {
$filter->check();
}
}
基于很多同學(xué)對接口簽名驗(yàn)證比較陌生,從框架推出簽名驗(yàn)證以來,很長一段時(shí)間內(nèi),很多同學(xué)對于如何實(shí)現(xiàn)一個接口簽名依然不知如何下手。
為了給大家更好的便利性,我們提供了一個基本版的接口驗(yàn)證服務(wù)。
主要是基于md5進(jìn)行的簽名生成,這個只能作為一般性的參考。大家可以在此基礎(chǔ)上進(jìn)行調(diào)整延伸。
默認(rèn)情況下,可以去掉注釋開啟使用PhalApi_Filter_SimpleMD5進(jìn)行接口驗(yàn)證,即:
//簽名驗(yàn)證服務(wù)
DI()->filter = 'PhalApi_Filter_SimpleMD5';
其驗(yàn)簽的算法如下(如注釋所示):
1、排除簽名參數(shù)(默認(rèn)是sign)
2、將剩下的全部參數(shù),按參數(shù)名字進(jìn)行字典排序
3、將排序好的參數(shù),全部用字符串拼接起來
4、進(jìn)行md5運(yùn)算
下面是兩個調(diào)用示例,錯誤請求下(即簽名失?。?
http://localhost/phalapi/public/demo/?service=Default.Index&username=dogstar
返回:
{
"ret": 406,
"data": [],
"msg": "非法請求:簽名錯誤"
}
溫馨提示:
簽名錯誤情況下,可以查看日志獲得正確的sign,如:
2015-10-23 23:16:16|DEBUG|Wrong Sign|{"needSign":"35321cc43cfc1e4008bf6f1bf9b7e3b8"}
正常請求下(帶sign簽名):
http://localhost/phalapi/public/demo/?service=Default.Index&username=dogstar&sign=35321cc43cfc1e4008bf6f1bf9b7e3b8
如果不想使用sign作為關(guān)鍵的簽名參數(shù),可以在注冊時(shí)指定,如使用縮寫s:
DI()->filter = new PhalApi_Filter_SimpleMD5('s');
所以,如果我們需要實(shí)現(xiàn)簽名驗(yàn)證,只需要簡單的兩步即可:
下面以大家熟悉的 微信驗(yàn)簽 為例,進(jìn)行示例說明。
通常我們約定返回ret = 402表示驗(yàn)證失敗,所以當(dāng)簽名失敗時(shí),我們可以返回ret = 402以告知客戶端簽名不對。根據(jù)微信的檢驗(yàn)signature的PHP示例代碼,我們可以快速實(shí)現(xiàn)自定義簽名規(guī)則,如:
//$ vim ./Demo/Common/SignFilter.php
<?php
class Common_SignFilter implements PhalApi_Filter
{
public function check()
{
$signature = DI()->request->get('signature');
$timestamp = DI()->request->get('timestamp');
$nonce = DI()->request->get('nonce');
$token = 'Your Token Here ...';
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if ($tmpStr != $signature) {
throw new PhalApi_Exception_BadRequest('wrong sign', 1);
}
}
}
隨后,我們只需要再簡單地注冊一下過濾器服務(wù)即可,在init.php初始化文件最后追加:
//$ vim ./Public/init.php
//簽名驗(yàn)證服務(wù)
DI()->filter = 'Common_SignFilter';
當(dāng)我們再次請求接口時(shí),如默認(rèn)的服務(wù):/demo/?service=Default.Index,即會出現(xiàn)以下的錯誤:
即:
{
"ret": 401,
"data": [
],
"msg": "非法請求:wrong sign"
}
如果符合接口簽名的驗(yàn)證,則會正常返回我們熟悉的內(nèi)容,如:
/demo/?service=Default.Index&signature=b75e0a1b574d4e111a1d6ed3c9cfbe2ccdc09404×tamp=123&nonce=123
會返回:
{
"ret": 200,
"data": {
"title": "Default Api",
"content": "PHPer您好,歡迎使用PhalApi!",
"version": "1.1.0",
"time": 1423055188
},
"msg": ""
}
在注冊好統(tǒng)一的接口驗(yàn)簽的過濾器攔截服務(wù)后,是會存在這樣一種情況:即個別的接口不需要簽名。
而這種情況,我們也是有考慮到的。所以在提供了公共的功能的情況下,我們是可以快速靈活地進(jìn)行定制化和擴(kuò)展。
當(dāng)我們個別的接口不需要簽名驗(yàn)證時(shí),只需要簡單地在接口子類里面重定義過濾器的檢測即可,如在我們熟悉的默認(rèn)服務(wù)器取消簽名驗(yàn)證:
//vim ./Demo/Api/Default.php
class Api_Default extends PhalApi_Api
{
//....
protected function filterCheck()
{
}
}
通常關(guān)于接口簽名這塊,我們還需要:
1、為不同的接入方定義不同的密鑰和私鑰;
2、如果業(yè)務(wù)需要,為各個接口、各個接入方分配調(diào)用權(quán)限;
/**
* 應(yīng)用接口層的統(tǒng)一參數(shù)
*/
'apiCommonRules' => array(
'signature' => array('name' => 'signature', 'require' => true),
'timestamp' => array('name' => 'timestamp', 'require' => true),
'nonce' => array('name' => 'nonce', 'require' => true),
),
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: