介面的安全性主要圍繞token、timestamp和sign三個機制展開設計,保證介面的資料不會被篡改和重複呼叫,下面具體來看:
(1)token授權機制:(token是客戶端訪問服務端的憑證)–使用者使用使用者名稱密碼登入後伺服器給客戶端返回乙個token(通常是uuid),並將token-userid以鍵值對的形式存放在快取伺服器中。服務端接收到請求後進行token驗證,如果token不存在,說明請求無效。
(2)時間戳超時機制:(簽名機制保證了資料不會被篡改)使用者每次請求都帶上當前時間的時間戳timestamp,服務端接收到timestamp後跟當前時間進行比對,如果時間差大於一定時間(比如5分鐘),則認為該請求失效。時間戳超時機制是防禦dos攻擊的有效手段。
(3)簽名機制:將 token 和 時間戳 加上其他請求引數再用md5或sha-1演算法(可根據情況加點鹽)加密,加密後的資料就是本次請求的簽名sign,服務端接收到請求後以同樣的演算法得到簽名,並跟當前的簽名進行比對,如果不一樣,說明引數被更改過,直接返回錯誤標識。
簡單的實現了介面校驗:登陸獲取到token
/**
* 模擬登陸 分配隨機token
* @route('login')
*/public function login()
return json($token);
}else
}
用php模擬客服端,登陸成功獲得token 並生成隨機數、時間戳、生成sign ,生成這些資料之後請求介面時,帶上相應的引數過去進行鑑權,鑑權驗籤部分用的工具就不貼**了。
//隨機生成字串
private function createnoncestr($length = 8)
return $str;
}/**
* @param $timestamp 時間戳
* @param $randomstr 隨機字串
* @return string 返回簽名
* @route('checklogin')
*/public function createsign($timestamp='',$token='',$randomstr='')
/*** @return mixed
* @route('userlogin')
*/public function login()
/*** @route('getradmon')
*/public function getdatafromserver()
接下來就是服務端鑑權**,服務端拿到timestamp、token、sign、randomstr等引數進行驗證過程
use think\facade\cache;
use think\facade\config;
use think\controller;
use think\facade\exception;
use think\db;
class common extends controller
if(empty($timestamp))
if(empty($randomstr))
if(empty($sign))
//檢驗token
$tokencheck = cache::get('1token');
if($tokencheck != $token )
//時間校驗
$timestamp1 = $timestamp+$exprie;
if( $timestamp1illegalip())
//按規則拼接為字串
$str = $this->arithmetic($timestamp,$token,$randomstr);
if($str != $sign)
if(!$this->ask_count())
return json('驗籤ok');
}/**
* @param $timestamp 時間戳
* @param $randomstr 隨機字串
* @return string 返回簽名
*/public function arithmetic($timestamp,$token,$randomstr)
/*** @desc 限制請求介面次數
* @return bool
*/private function ask_count()
}//執行插入
$add_data = array(
'ip_name'=>$client_ip,
'ask_url'=>$ask_url,
'creatime'=>date('y-m-d h:i:s',time())
);$result = db::name('log_ip_ask')->insert($add_data);
if($result===false)
return true;
}/**
* @desc 非法ip限制訪問
* @param array $config
* @return bool
*/private function illegalip()
$remote_ip = getclientip();
if(in_array($remote_ip, $this->ip_limit))
return true;
}/**
* 模擬登陸 分配隨機token
* @route('login')
*/public function login()
return json($token);
}else
}} 最後還有幾個公用的方法和配置
'expire'=>5*6000000,//api有效期
'api_ask_limit'=>10,//api訪問次數
'api_ask_time'=>60,
common中的函式
/**
* 獲取客戶端ip位址
* @param integer $type 返回型別 0 返回ip位址 1 返回ipv4位址數字
* @param boolean $adv 是否進行高階模式獲取(有可能被偽裝)
// ip位址合法驗證
$long = sprintf("%u",ip2long($ip));
$ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
return $ip[$type];
}/**
* @desc php獲取當前訪問的完整url位址
* @return string
*/function geturl()
if ($_server ['server_port'] != '80') else
return $url;
}/**
* * curl模擬get請求
*/function httpget($url)
以上還有可改進的地方,限制ip、次數等。大家有什麼好的建議可以說一下。
參考:
增量介面的設計及實現
在應用開發過程中,我們總會碰到這樣的場景 某系統需要同步我們系統的資料去做一些業務邏輯,當資料量較小的時候,可以全量的提供,但當資料量很大時,全量提供就顯得很笨重,不僅耗時而且做了很多無用功,這時我們需要一種提供增量資料的機制,只告訴對方變化的資料。提供增量資料大致可分為兩種方式 mq和介面提供,m...
php介面的安全設計要素 Token,簽名,時間戳
後端以api的方式將資料來源呈現出來是目前的趨勢,可以用在前後端分離的架構中,前後端分離之後,前後端人員能夠更加專注於自己板塊的東西 也可以用在後端與後端相互呼叫中。拿到介面後,前台就可以通過鏈結獲取介面提供的資料,而返回的資料一般分為兩種情況,xml和json,在這個過程中,伺服器並不知道,請求的...
PHP 安全及相關
關注安全問題的重要性 看到的遠非全部 function write text filename,text return true index md5 filename if isset open files index fputs open files index text return true ...