========== ===================== ======================== HTTP 方法 行爲 示例 ========== ===================== ======================== GET 獲取資源的信息 http://xx.com/api/orders GET 獲取某個特定資源的信息 http://xx.com/api/orders/123 POST 建立新資源 http://xx.com/api/orders PUT 更新資源 http://xx.com/api/orders/123 DELETE 刪除資源 http://xx.com/api/orders/123 ========== ====================== =======================
對於請求的數據通常用json或者xml形式來表示,推薦使用json。php
2.1 HTTP Basicweb
REST因爲是無狀態的傳輸,因此每一次請求都得帶上身份認證信息,身份認證的方式,身份認證的方式有不少種,第一種即是http basic,這種方式在客戶端要求簡單,在服務端實現也很是簡單,只需簡單配置apache等web服務器便可實現,因此對於簡單的服務來講仍是挺方便 的。可是這種方式安全性較低,就是簡單的將用戶名和密碼base64編碼放到header中。正則表達式
base64編碼前:Basic admin:admin base64編碼後:Basic YWRtaW46YWRtaW4= 放到Header中:Authorization: Basic YWRtaW46YWRtaW4=
正是由於是簡單的base64編碼存儲,切記切記在這種方式下必定得注意使用ssl,否則就是裸奔了。redis
在某些產品中也是基於這種相似方式,只是沒有使用apache的basic機制,而是本身寫了認證框架,原理仍是同樣的,在一次請求中base64 解碼Authorization字段,再和認證信息作校驗。很顯然這種方式有問題,認證信息至關於明文傳輸,另外也沒有防暴力破解功能。算法
2.2 API KEY數據庫
API Key就是通過用戶身份認證以後服務端給客戶端分配一個API Key,相似:http://example.com/api?key=dfkaj134
,通常的處理流程以下:apache
一個簡單的設計示例以下:json
client端:api
server端:緩存
client端向服務端註冊,服務端給客戶端發送響應的api_key以及security_key,注意保存不要泄露,而後客戶端根據 api_key,secrity_key,timestrap,rest_uri採用hmacsha256算法獲得一個hash值sign,構造途中的 url發送給服務端。
服務端收到該請求後,首先驗證api_key,是否存在,存在則獲取該api_key的security_key,接着驗證timestrap是否 超過期間限制,可依據系統成而定,這樣就防止了部分重放攻擊,途中的rest_api是從url獲取的爲/rest/v1/interface /eth0,最後計算sign值,完以後和url中的sign值作校驗。這樣的設計就防止了數據被篡改。
經過這種API Key的設計方式加了時間戳防止了部分重放,加了校驗,防止了數據被篡改,同時避免了傳輸用戶名和密碼,固然了也會有必定的開銷。
2.3 Oauth1.0a或者Oauth2
OAuth協議適用於爲外部應用受權訪問本站資源的狀況。其中的加密機制與HTTP Digest身份認證相比,安全性更高。使用和配置都比較複雜,這裏就不涉及了。
2.4 JWT
JWT 是JSON Web Token,用於發送可經過數字簽名和認證的東西,它包含一個緊湊的,URL安全的JSON對象,服務端可經過解析該值來驗證是否有操做權限,是否過時等 安全性檢查。因爲其緊湊的特色,可放在url中或者 HTTP Authorization頭中,具體的算法就以下圖
1
2
3
4
5
6
7
8
9
10
|
$roles = array (
'ADMIN' => array (
'permit' => array ( '/^((\/system\/(clouds|device)$/' ), // 容許訪問哪些URL的正則表達式
'deny' => array ( '/^(\/system\/audit)$/' ) // 禁止訪問哪些URL的正則表達式
),
'AUDIT' => array (
'permit' => array ( '/^(\/system\/audit)$/' ), //容許訪問的URL正則表達式
'deny' => array ( '/^((\/system\/(clouds|device).*)$/' )
)
);
|
上述是垂直權限的處理,若是遇到了平行權限的問題,如用戶A獲取用戶B的身份信息或者更改其餘用戶信息,對於這些敏感數據接口都須要加上對用戶的判斷,這一步通常都在具體的邏輯實現中實現。
在進入邏輯處理以前,加入對URL的參數過濾,如/site/{num}/policy
限定num位置爲整數等,若是不是參數則直接返回非法參數,設定一個url清單,不在不在url清單中的請求直接拒絕,這樣能防止開發中的api泄露。 rest api接口通常會用到GET,POST,PUT,DELETE,未實現的方法則直接返回方法不容許,對於POST,PUT方法的數據採用json格式,並 且在進入邏輯前驗證是否json,不合法返回json格式錯誤。
第一步推薦SSL加密傳輸,同時對於系統中重要的功能作加密傳輸,如證書,一些數據,配置的備份功能,同時還得確保具有相應的權限,這一步會在受權中涉及。
請求速率限制,根據api_key或者用戶來判斷某段時間的請求次數,將該數據更新到內存數據庫(redis,memcached),達到最大數即 不接受該用戶的請求,同時這樣還能夠利用到內存數據庫key在特定時間自動過時的特性。在php中可使用APC,Alternative PHP Cache (APC) 是一個開放自由的PHP opcode 緩存。它的目標是提供一個自由、 開放,和健全的框架用於緩存和優化PHP的中間代碼。在返回時設置X-Rate-Limit-Reset:當前時間段剩餘秒數,APC的示例代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Route::filter( 'api.limit' , function ()
{
$key = sprintf( 'api:%s' , Auth::user()->api_key);
// Create the key if it doesn't exist
Cache::add( $key , 0, 60);
// Increment by 1
$count = Cache::increment( $key );
// Fail if hourly requests exceeded
if ( $count > Config::get( 'api.requests_per_hour' ))
{
App::abort(403, 'Hourly request limit exceeded' );
}
});
|
{"result":"Invalid
URL!"},錯誤的請求參數{"result":"json format error"}
,不容許的方法:{"result":"Method Not Allowed"}
,非法參數等。上面所說的都是單狀態碼,同時還有多狀態碼,表示部分紅功,部分字符非法等。示例以下:
HTTP/1.1 207 Multi-Status Content-Type: application/json; charset="UTF-8" Content-Length: XXXX { "OPT_STATUS": 207 "DATA": { "IP_ADDRESS": [{ "INTERFACE": "eth0", "IP_LIST":[{ "IP": "192.168.1.1", "MASK": "255.255.0.0", "MULTI_STATUS": 200, "MULTI_RESULT": "created successfully" },{ "IP": "192.167.1.1", "MASK": "255.255.0.0", "MULTI_STATUS": 409, "MULTI_RESULT": "invalid parameter" }] }] },
(2)返回數據統一編碼格式,統一返回類型,如Content-Type: application/json; charset="UTF-8"
(3)在邏輯實現中,json解碼以後進行參數驗證或者轉義操做,第一步json格式驗證,第二步具體參數驗證基本上能防止大部分的注入問題了。
(4)在傳輸過程當中,採用SSL保證傳輸安全。
(5)存儲安全,重要信息加密存儲,如認證信息hash保存。
總之,儘可能使用SSL。
REFER:
http://blog.nsfocus.net/rest-api-design-safety/
http://drops.wooyun.org/web/9737