Rest介紹
REST(Representational State Transfer)是一種軟件架構(gòu)風(fēng)格,用于設(shè)計(jì)網(wǎng)絡(luò)服務(wù)和API。它是由Roy Fielding在他的博士論文中提出,并成為HTTP協(xié)議的基石之一。
REST基于以下幾個(gè)主要原則:
- 資源(Resources):將系統(tǒng)中的每個(gè)實(shí)體(如用戶(hù)、產(chǎn)品、訂單等)都視為一個(gè)資源,每個(gè)資源可以通過(guò)唯一的標(biāo)識(shí)符進(jìn)行訪問(wèn)。
- 統(tǒng)一接口(Uniform Interface):使用統(tǒng)一的接口來(lái)處理資源,包括使用HTTP動(dòng)詞(GET、POST、PUT、DELETE等)進(jìn)行操作,并通過(guò)URI(資源標(biāo)識(shí)符)來(lái)定位資源。
- 無(wú)狀態(tài)(Stateless):服務(wù)器不會(huì)存儲(chǔ)客戶(hù)端的狀態(tài)信息,每個(gè)請(qǐng)求都應(yīng)該包含足夠的信息以完成請(qǐng)求處理。
- 按需響應(yīng)(Response on Demand):服務(wù)器按照客戶(hù)端請(qǐng)求的內(nèi)容返回相應(yīng)的數(shù)據(jù),可以是html、JSON、XML等格式。
- 可緩存性(Caching):對(duì)于可緩存的響應(yīng),客戶(hù)端可以緩存結(jié)果以提高性能和減少對(duì)服務(wù)器的請(qǐng)求。
Rest示例
下面是一個(gè)簡(jiǎn)單的REST示例,以管理用戶(hù)資源為例:
- 獲取用戶(hù)列表:發(fā)送GET請(qǐng)求來(lái)獲取所有用戶(hù)信息。
GET /users
- 獲取特定用戶(hù):發(fā)送GET請(qǐng)求來(lái)獲取特定用戶(hù)的詳細(xì)信息。使用用戶(hù)ID作為路徑參數(shù)。
GET /users/{user_id}
- 創(chuàng)建用戶(hù):發(fā)送POST請(qǐng)求來(lái)創(chuàng)建新用戶(hù)。請(qǐng)求體中包含新用戶(hù)的信息。
POST /users
Request Body:
{
"name": "John Doe",
"emAIl": "[email protected]",
"age": 25
}
- 更新用戶(hù):發(fā)送PUT請(qǐng)求來(lái)更新特定用戶(hù)的信息。使用用戶(hù)ID作為路徑參數(shù),并在請(qǐng)求體中包含更新后的用戶(hù)信息。
PUT /users/{user_id}
Request Body:
{
"name": "Jane Smith",
"email": "[email protected]",
"age": 30
}
- 刪除用戶(hù):發(fā)送DELETE請(qǐng)求來(lái)刪除特定用戶(hù)。使用用戶(hù)ID作為路徑參數(shù)。
DELETE /users/{user_id}
Rest優(yōu)點(diǎn)
用了這么多年 Rest,總結(jié)幾個(gè)優(yōu)點(diǎn)(從上述示例也可以看出)。
- Rest 具備規(guī)范性,GET/POST/PUT/DELETE 分別代表 獲取/創(chuàng)建/修改/刪除 操作。
- Rest 表意明確,可讀性強(qiáng),代碼清晰。
- GET/PUT/DELETE 都是冪等的,若操作失敗,可以進(jìn)行重試,確保資源的一致性。一些框架可以基于此特性做一些重試機(jī)制。
但是最近的一系列安全問(wèn)題,最終我們放棄了Rest。
安全問(wèn)題
由于我們是 ToG 行業(yè),沒(méi)有什么比安全更大的問(wèn)題,任何技術(shù)的先進(jìn)性在安全性面前都不值得一提。以下是著重碰到的安全問(wèn)題:
- 國(guó)產(chǎn)安全軟件(深信服等)將 PUT/DELETE 直接定性為非法請(qǐng)求,所有的此類(lèi)請(qǐng)求都需要修改成 POST。以前的方案是我們?cè)谇岸私y(tǒng)一將 PUT/DELETE 改成 POST,在 HEADER 中將原始請(qǐng)求類(lèi)型作為參數(shù)帶到請(qǐng)求中,后端網(wǎng)關(guān)層統(tǒng)一將 POST 轉(zhuǎn)為原始請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的服務(wù)(前端和后端基本都不用改)。
- 暴力遍歷問(wèn)題。如 GET /users/{user_id} ,不法分子可以使用下述請(qǐng)求暴力獲取數(shù)據(jù),存在安全隱患。最近碰到個(gè)銀行系統(tǒng),必須要整改!!
GET /users/1
GET /users/2
GET /users/3
GET /users/...
GET /users/n
- 數(shù)據(jù)越權(quán)問(wèn)題。前端請(qǐng)求 token 與請(qǐng)求參數(shù)代表的用戶(hù)不一致,如 token 代表是 A 用戶(hù),但實(shí)際請(qǐng)求的 GET /order/{order_id} 中 order_id 是 B/C/D/E/.../N 用戶(hù)的,存在數(shù)據(jù)越權(quán)訪問(wèn)。必須整改!!!
- 請(qǐng)求明文問(wèn)題。用 GET 請(qǐng)求在參數(shù)中都是明文傳輸,直接可以通過(guò)瀏覽器 F12 就能看到請(qǐng)求參數(shù),不安全!!!
解決方案
將所有請(qǐng)求都改成 POST ,請(qǐng)求參數(shù)放在 Body 中,前端做一層簡(jiǎn)單的簽名和加密。F12看不出來(lái)、安全工具也掃不出來(lái),萬(wàn)事大吉!!






