open api 是什麼? Open API即開放API,也稱開放接口 所謂的開放API(OpenAPI)是服務型網站常見的一種應用,網站的服務商將本身的網站服務封裝成一系列API(Application Programming Interface,應用編程接口)開放出去,供第三方開發者使用,這種行爲就叫作開放網站的API,所開放的API就被稱做OpenAPI(開放API)。 (摘自百科,主要爲了說一下概念)mysql
常見的設計是: 必備的有:app key 與 app secret 簽名 可選的有: 企業ID, 業務ID。 這些可選的東西通常用來區分業務領域或者權限而存在,確保不一樣調用者領域與權限的隔離。git
app key 與app secret 是我見過最多見,也是必然會出現的一個設計, 在我對接過的十多種API(阿里、騰訊、小米)中, 這這些都是必備的。github
主要是爲了防止請求被篡改以及用戶識別。通常一個 app key 是用於作用戶識別的, 服務提供方通常會存放調用方的一些信息, 並能夠經過這個App key 檢索到。golang
app secret 主要是用來簽名請求的, 簽名過的請求若是被修改以後, 則簽名就會發生變化,攻擊者是不可能知道這個變化的結果的,這樣能夠有效防止攻擊者的攻擊。web
通常來說,會對以下領域進行簽名:sql
通常的流程以下:編程
如何頒發? 通常是由服務提供方生成這樣的一個鍵值對, 並把鍵值對安全的遞給調用方。 之後 app secret 不會出如今網絡傳輸中,只會用於雙方的簽名校驗。api
這個是最多見的一種, 它不須要知道服務提供方與三方的祕鑰, 只須要知道,雙方的通訊方式, 經過分析這種通訊方式,來達到竊取信息,或者形成攻擊的目的。 這種行爲的防範方法也是有一些的: 在請求裏面加上時間信息,對時間信息進行加密簽名, 對時間設置可用時間段, 好比1分鐘, 過了一分鐘,攻擊者獲取到的信息就不能再用了。安全
祕鑰泄露對於不少企業來講並不陌生, 一旦泄露對於雙方的危害都很大, 並且若是不能及時發現會帶來不小的損失, 這種人爲泄漏, 不少時候並無太好的辦法。 能夠作的事情比較現實的就是更換祕鑰。服務器
調用服務方提供的Open API的三方合做者, 有可能對服務提供方形成壓力過大的攻擊, 這種攻擊主要來源於兩種途徑:
對於穿透的攻擊: 服務提供方能作的最多見的方案就是限流, 另外就是流量識別, 在流量異常的時候對API接口自己作一些限制
固然安全防範確實還有不少須要考慮的點,通常都會結合攻擊的特色, 對於攻擊類型進行定製防範, 對於業界常見的防範措施,通常都是要默認加入的。
openapi 它主要解決的問題是: 簡化服務端提供API的流程
這個工具是用golang設計的, 所以只適用於golang的項目。 因爲這個工具是基於 http.Request
進行設計的, 所以理論上講兼容全部的web框架, 如 gin
, iris
, beego
等, 我在readme裏面提供了iris
的示例代碼
若是使用mysql來存放app key 和secret信息, 能夠建以下的一個表
CREATE TABLE `app` (
`app_key` varchar(32) NOT NULL,
`app_secret` varchar(128) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`app_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
複製代碼
若是已經存在這樣一個相似的表也能夠不用創建,在代碼中指定便可
r, err := openapi.CheckValid(req,
// default implementation is via sql, to fetch the secrect
openapi.SqlSecretKeeper{
Db: store.GetDb(), // 可使用的 mysql 鏈接
TableName: "app", // 存放app key 和secrets的表名
KeyCol: "app_key", // app key 的列名
SecretCol: "app_secret", // app secret的列名
AppKey: k, // 用戶使用的 app key
})
複製代碼
固然若是您已經封裝好了app key 與secret的邏輯, 也能夠本身實現以下接口
// the interface to get the secret
type SecretKeeper interface {
GetSecret() (string, error)
}
複製代碼
對於使用了web 框架的,只須要寫一個middleware, 並啓用就好了, 示例代碼以下:
建立middleware
// create a middle ware for iris
func OpenApiHandler(ctx iris.Context) {
//sign header? to prevent header being modified by others
// openapi.SignHeader(true)
req := ctx.Request()
// you can put the key somewhere in the header or url params
k := ctx.URLParam("app_key")
r, err := openapi.CheckValid(req,
// default implementation is via sql, to fetch the secrect
openapi.SqlSecretKeeper{
Db: store.GetDb(),
TableName: "app", // the name of table where you store all your app keys and secretcs
KeyCol: "app_key", // the column name of the app keys
SecretCol: "app_secret", // the column name of the app secrets
AppKey: k, // the app key that the client used
})
logError(err)
if r {
// verfy success, continue the request
ctx.Next()
} else {
// verify fail, stop the request and return
ctx.Text(err.Error())
ctx.StopExecution()
return
}
}
複製代碼
啓用middleware
// use the middle ware somewhere
// so all the apis under this group should be
// called with signed result and app key
openApiGroup := app.Party("/open")
openApiGroup.Use(OpenApiHandler)
{
openApiGroup.Get("/app", func(ctx iris.Context) {
ctx.Text("success")
})
}
複製代碼
是否是很簡單,若是文中有誤,或者缺失的內容歡迎各類批評教育。
若是您能讀到這裏, 我會感受到十分榮幸,謝謝您的關注。