在做一些api接口設(shè)計(jì)時(shí)候會(huì)遇到設(shè)置權(quán)限問題,比如我這個(gè)接口只有指定的用戶才能訪問。
很多時(shí)候api接口是屬于無狀態(tài)的,沒辦法獲取session,就不能夠用登錄的機(jī)制去驗(yàn)證,那么
大概的思路是在請(qǐng)求包帶上我們自己構(gòu)造好的簽名,這個(gè)簽名必須滿足下面幾點(diǎn):
a、唯一性,簽名是唯一的,可驗(yàn)證目標(biāo)用戶
b、可變性,每次攜帶的簽名必須是變化的
c、時(shí)效性,具有一定的時(shí)效,過期作廢
d、完整性,能夠?qū)?shù)據(jù)包進(jìn)行驗(yàn)證,防止篡改
直接看下面代碼
<?php
// 設(shè)置一個(gè)公鑰(key)和私鑰(secret),公鑰用于區(qū)分用戶,私鑰加密數(shù)據(jù),不能公開
$key ="c4ca4238a0b923820dcc509a6f75849b";$secret ="28c8edde3d61a0411511d3b1866f0636";
// 待發(fā)送的數(shù)據(jù)包
$data =array('username'=>'abc@qq.com','sex'=>'1','age'=>'16','addr'=>'guangzhou','key'=> $key,'timestamp'=> time(),);
// 獲取sign
functiongetSign($secret, $data){
// 對(duì)數(shù)組的值按key排序
ksort($data);
// 生成url的形式
$params = http_build_query($data);
// 生成sign
$sign = md5($params . $secret);return$sign;}
// 發(fā)送的數(shù)據(jù)加上sign$data['sign'] = getSign($secret, $data);
/** * 后臺(tái)驗(yàn)證sign是否合法 *@param[type] $secret [description] *@param[type] $data? [description] *@return[type]? ? ? ? [description] */
functionverifySign($secret, $data){
// 驗(yàn)證參數(shù)中是否有簽名
if(!isset($data['sign']) || !$data['sign']) {
echo'發(fā)送的數(shù)據(jù)簽名不存在';die();? ??
}
if(!isset($data['timestamp']) || !$data['timestamp']) {
echo'發(fā)送的數(shù)據(jù)參數(shù)不合法';die();? ?
?}
// 驗(yàn)證請(qǐng)求, 10分鐘失效
if(time() - $data['timestamp'] >600) {
echo'驗(yàn)證失效, 請(qǐng)重新發(fā)送請(qǐng)求';die();? ?
?}? ?
?$sign = $data['sign'];unset($data['sign']);?
?? ksort($data);? ??
$params = http_build_query($data);
// $secret是通過key在api的數(shù)據(jù)庫中查詢得到
$sign2 = md5($params . $secret);if($sign == $sign2) {
die('驗(yàn)證通過');??
?}else{
die('請(qǐng)求不合法');? ??
}}?>