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")
})
}
复制代码
是否是很简单,若是文中有误,或者缺失的内容欢迎各类批评教育。
若是您能读到这里, 我会感受到十分荣幸,谢谢您的关注。