相對安全的 restful api
隨著公司業務漸漸壯大,為了降低系統之間的耦合度,提高系統與系統之間的協作效率。可能部分業務將 採用 api 方式進去資料操作,但是基於 HTTP 協議方式傳遞資料會涉及到下列三個基礎問題:
資料提交者是否合法?
資料傳遞期間是否被篡改?
資料是否被多次提交?
如何解決以上三個問題呢? so easy !
一些常見的 SDK 裡面已經涉及到這些問題,細心的童靴已經發現瞭解決方案。
解決資料提交是否合法、資料是否被篡改
客戶端和服務端約定簽名演算法,客戶端生成簽名作為資料傳遞的一個欄位,服務端拿到簽名進行合法性驗證。常見的簽名步驟如下:
服務端提供方給出app_id和app_secret
- 客戶端端根據app_id和app_secret以及請求引數,按照一定演算法生成簽名sign
- 服務端進行驗證簽名
具體以支付寶簽名為例子(PHP版本,客戶端)
<?php
class sign{
/**
* 生成要請求給支付寶的引數陣列
* @param $para_temp 請求前的引數陣列
* @return 要請求的引數陣列
*/
function buildRequestPara($para_temp, $app_secret = '', $sign_type = 'MD5') {
//除去待簽名引數陣列中的空值和簽名引數
$para_filter = $this->paraFilter($para_temp);
//對待簽名引數陣列排序
$para_sort = $this->argSort($para_filter);
//生成簽名結果
$mysign = $this->buildRequestMysign($para_sort, $app_secret);
//簽名結果與簽名方式加入請求提交引數組中
$para_sort['sign'] = $mysign;
$para_sort ['sign_type'] = strtoupper(trim($sign_type));
return $para_sort;
}
/**
* 獲取返回時的簽名驗證結果
* @param $para_temp 通知返回來的引數陣列
* @param $sign 返回的簽名結果
* @return 簽名驗證結果
*/
function getSignVeryfy($para_temp, $sign, $app_secret = '', $sign_type = 'MD5') {
//除去待簽名引數陣列中的空值和簽名引數
$para_filter = $this->paraFilter($para_temp);
//對待簽名引數陣列排序
$para_sort = $this->argSort($para_filter);
//把陣列所有元素,按照“引數=引數值”的模式用“&”字元拼接成字串
$prestr = $this->createLinkstring($para_sort);
$isSgin = false;
switch (strtoupper(trim($sign_type))) {
case "MD5" :
$isSgin = $this->md5Verify($prestr, $sign, $app_secret);
break;
default :
$isSgin = false;
}
return $isSgin;
}
/**
* 生成簽名結果
* @param $para_sort 已排序要簽名的陣列
* return 簽名結果字串
*/
function buildRequestMysign($para_sort, $app_secret, $sign_type = 'MD5') {
//把陣列所有元素,按照“引數=引數值”的模式用“&”字元拼接成字串
$prestr = $this->createLinkstring($para_sort);
$mysign = "";
switch (strtoupper(trim($sign_type))) {
case "MD5" :
$mysign = $this->md5Sign($prestr, $app_secret);
break;
default :
$mysign = "";
}
return $mysign;
}
/**
* 把陣列所有元素,按照“引數=引數值”的模式用“&”字元拼接成字串
* @param $para 需要拼接的陣列
* return 拼接完成以後的字串
*/
function createLinkstring($para) {
$arg = "";
while (list ($key, $val) = each ($para)) {
$arg.=$key."=".$val."&";
}
//去掉最後一個&字元
$arg = substr($arg,0,count($arg)-2);
//如果存在轉義字元,那麼去掉轉義
if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
return $arg;
}
/**
* 簽名字串
* @param $prestr 需要簽名的字串
* @param $key 私鑰
* return 簽名結果
*/
function md5Sign($prestr, $key) {
$prestr = $prestr . $key;
return md5($prestr);
}
/**
* 驗證簽名
* @param string $prestr 需要簽名的字串
* @param string $sign 簽名結果
* @param string $key 私鑰
* return boolean 簽名結果
*/
function md5Verify($prestr, $sign, $key) {
$prestr = $prestr . $key;
$mysgin = md5($prestr);
if($mysgin == $sign) {
return true;
}
else {
return false;
}
}
/**
* 除去陣列中的空值和簽名引數
* @param $para 簽名引數組
* return 去掉空值與簽名引數後的新簽名引數組
*/
function paraFilter($para) {
$para_filter = array();
while (list ($key, $val) = each ($para)) {
if($key == "sign" || $key == "sign_type" || $val == "")continue;
else $para_filter[$key] = $para[$key];
}
return $para_filter;
}
/**
* 對陣列排序
* @param $para 排序前的陣列
* return 排序後的陣列
*/
function argSort($para) {
ksort($para);
reset($para);
return $para;
}
}
include './httplib.class.php';// 基礎的 curl
include './sign.class.php';
$app_id = 'demo';
$app_secret = 'your secret';
$time = time();
$data = [
'uid' => '1',
'name' => 'kevin',
'age' => '25',
'fid' => '1',
'_timestamp' => $time,
];
$sign = new sign();
$params = $sign->buildRequestPara($data, $app_secret);
$http = new httplib();
$request_url = 'http://127.0.0.1/sign_response.php';// 服務端介面地址
$http->request($request_url, $params);
服務端介面處理
include './sign.class.php';
$app_id = 'demo';
$app_secret = 'your secret';
$sign = new sign();
$data = $_POST; // 未做安全處理
if(!isset($data['sign']) || empty($data['sign']))
{
echo '缺少簽名引數';exit;
}
$sign = new sign();
if($sign->getSignVeryfy($data, $data['sign'], $app_secret)) {
echo '簽名認證成功,繼續你的業務邏輯';
} else {
echo '簽名失敗';
}
執行結果
關於多次提交客服端可相對判定
- 上面的栗子可以根據一個時間戳欄位 _timestamp 在相對時間內請求多次。
if(!isset($data['_timestamp']) || empty($data['_timestamp']))
{
echo '缺少時間引數';exit;
}
$nowtime = time();
// 120 秒 即 2分鐘內 請求是有效的,客服端和服務端時間可能有差異,此判斷不是客觀的,根據時間情況參訂
if(($nowtime-intval($data['_timestamp'])) > 120)
{
echo '缺少時間引數';exit;
}
- 以上只是相對判定,服務端當然也可以儲存客戶端請求,下次進行判定,當然成本很高。服務端也可以生成 一次性token,客戶端得到此token傳遞資料時候帶上token 服務端再次驗證token的有效性
相關推薦
相對安全的 restful api
隨著公司業務漸漸壯大,為了降低系統之間的耦合度,提高系統與系統之間的協作效率。可能部分業務將 採用 api 方式進去資料操作,但是基於 HTTP 協議方式傳遞資料會涉及到下列三個基礎問題: 資料提交者是否合法? 資料傳遞期間是否被篡改? 資料是否被多
Node.js: Securing RESTful APIs Node.js:開發安全的RESTful API Lynda課程中文字幕
Node.js: Securing RESTful APIs 中文字幕 Node.js:開發安全的RESTful API 中文字幕Node.js: Securing RESTful APIs API是將資料傳遞到應用程式的關鍵業務驅動程式 在本課程中,瞭解保護您的RESTful A
使用 JWT 讓你的 RESTful API 更安全
傳統的 cookie-session 機制可以保證的介面安全,在沒有通過認證的情況下會跳轉至登入介面或者呼叫失敗。 在如今 RESTful 化的 API 介面下,cookie-session 已經不能很好發揮其餘熱保護好你的 API 。 更多的形式下采用的基於 Token 的驗證機制,JWT 本質的也是一種
安全優雅的RESTful API簽名實現方案
安全優雅的RESTful API簽名實現方案 1、介面簽名的必要性 在為第三方系統提供介面的時候,肯定要考慮介面資料的安全問題,比如資料是否被篡改,資料是否已經過時,資料是否可以重複提交等問題。其中我認為最終要的還是資料是否被篡改。在此分享一下我的關於介面簽名的實踐方案。 2、專案中籤名方案痛點 每個介面有
RESTful API 設計指南
head 簡單 option eat set 取出 tro 其他 first 網絡應用程序,分為前端和後端兩個部分。當前的發展趨勢,就是前端設備層出不窮(手機、平板、桌面電腦、其他專用設備……)。 因此,必須有一種統一的機制,方便不同的前端設備與後端進行通信。這
Yii2 Restful Api 401
原因 數據 app -s style font code ont ram 采用Yii2 Restful Api方式為APP提供數據,默認你已經做好了所有的編碼和配置工作。采用Postman測試接口: 出現這個畫面的一個可能原因是:access_token的寫法有誤,如果你
Restful API設計
rfc mage erro art 狀態 存在 asc tar 區分 理解RESTful架構 越來越多的人開始意識到,網站即軟件,而且是一種新型的軟件。 這種"互聯網軟件"采用客戶端/服務器模式,建立在分布式體系上,通過互聯網通信,具有高延時(high latency
3.Spring Boot中使用Swagger2構建強大的RESTful API文檔
pack 效果 type 現象 業務邏輯 blank depend imp any 原文:http://www.jianshu.com/p/8033ef83a8ed 由於Spring Boot能夠快速開發、便捷部署等特性,相信有很大一部分Spring Boot的用戶會用來構
[CI] 使用CodeIgniter框架搭建RESTful API服務
解釋 valid 源碼 stat target 面向服務 prot 多次 1.0 在2011年8月的時候,我寫了一篇博客《使用CodeIgniter框架搭建RESTful API服務》,介紹了RESTful的設計概念,以及使用CodeIgniter框架實現RESTful
關於RestFul API 介紹與實踐
clas 分享 ice div 之前 api 設計 article alt 之前演示的PPT,直接看圖。。。 ?參考鏈接: ?RESTful API 設計最佳實踐 ?RESTful API 設計指南 ?SOAP webserivce和 RESTfulwebse
Yii2框架RESTful API教程(一) - 快速入門
比較 exp values cnblogs -- restful extends .cn pat 前不久做一個項目,是用Yii2框架寫一套RESTful風格的API,就去查了下《Yii 2.0 權威指南 》,發現上面寫得比較簡略。所以就在這裏寫一篇教程貼,希望幫助剛接觸Yi
Yii2框架RESTful API教程(二) - 格式化響應,授權認證和速率限制
formatter loginurl 而不是 filters ica cat 表示 程序 ssi 之前寫過一篇Yii2框架RESTful API教程(一) - 快速入門,今天接著來探究一下Yii2 RESTful的格式化響應,授權認證和速率限制三個部分 一、目錄結構 先
HTTP請求封裝:Ajax、RESTful API及Promise
active 技術 scrip XML end delete 我們 encode 完整 一、HTTP請求 HTTP即超文本傳輸協議,用以進行HTML 文件、 圖片文件、 查詢結果等的網絡傳輸。 一個完整的HTTP請求包括:請求行、請求頭、空行和請求數據(請求數據可以為
Restful API 設計參考原則
width 包裝 修改 api開發 司機 word 屬性 add 數據返回 在項目中,需要為後臺服務撰寫API。剛開始接觸的時候,並沒有考慮太多,就想提供URL,服務端通過該URL進行查詢、創建、更新等操作即可。但再對相關規範進行了解後,才發現,API的設計並沒有那麽簡單,
【API設計】RESTful API 設計指南
sys i/o ani sta 所有 com 訪問 指定 名詞 RESTful API URL定位資源,用HTTP動詞(GET,POST,DELETE,DETC)描述操作。 例如 1. REST描述的是在網絡中client和server的一種交互形式;REST本身不實
Python Restful API設計規範
探討 資源 表現層 gin htm 異步任務 sci 在服務器 type Python 之路,Restful API設計規範 理解RESTful架構 Restful API設計指南 理解RESTful架構 越來越多的人開始意識到,網站即軟件
開源的 Restful Api 集成測試工具 Hitchhiker
工具 use hub gif bsp res restful restfu ont https://github.com/brookshi/Hitchhiker 開源的 Restful Api 集成測試工具 Hitchhiker
RESTful API設計規範收集
版本控制 執行 tap cep 冪等性 解耦 sdn hyperlink radi 說明:其實沒有絕對的規範,達到90%即可。 理解RESTful架構:http://www.ruanyifeng.com/blog/2011/09/restful.html RESTful
我的C#跨平臺之旅(二):開發一組標準的Restful API
ref 運行 mar margin bruce ora soft left 啟用 添加NuGet引用:Microsoft.AspNet.WebApi.Owin 在啟動類啟用WebApi; 添加一個Controller類,代碼如下: 運行程序
Yii restful api跨域
tab ray request xtend host accep resource exp return 問題:NO ‘Access-Control_Allow-Origin‘ header is present on the requested resource.解決方案