当我们在提供一个服务时,除了面向用户提供界面操作外,还会面向各种三方开发者,那么此时服务的接口认证就很重要了。
下面来简单说说怎么设计一个接口的认证:API签名机制
API签名可以理解为就是对API的调用进行签名保护。是在进行API调用时,加了一个调用者及其调用行为的指纹信息,以帮助服务端更好的识别用户及其调用行为的合法性。其直接目的归纳为: (1)明确调用者的身份(确认调用者是谁) (2)明确调用者的调用行为(确认调用者想要做什么)
由此可见,API签名的真正目的是:通过明确调用者的身份,以便控制API的访问权限,从而保护数据的安全性。
我们都知道,在程序的世界中,很难找到一个稳定且唯一的信息去标识一个调用者,因为调用者本身的信息(如IP、设备等)也是不固定的,所以,标识调用者最好的方法就是服务端统一分配,具体过程大致如下:
以上流程的问题,在于SecretID是明文显示的,很容易被窃取和伪造;但SecretID又不能隐藏或加密,因为SecretID需要明确告诉服务端:我是谁?
所以,需要在SecretID之外,增加一个和SecretID绑定的信息,我们称之为:用户密钥 用户密钥(即SecretKey)就是为了验证用户身份用的,为了提高其安全性能,必须保证
如何知道用户的调用行为呢?一般就是把调用行为涉及的关键信息都放到签名内容中进行签名。那么,哪些是关键信息呢?
对于恶意攻击者,截取一个合法请求后,不停地使用该请求对服务端进行攻击;这种攻击可能造成重访攻击。 实现的方法,也很简单,那就是调用者每次调用时:
那么,另一个可行的办法,就是调用者每次请求时带上当前请求时间点Timestamp,然后由服务端限制请求的时效性。 即某个请求,其请求时间戳Timestamp,和服务端的当前时间在规定时间内(如1分钟内)则为合法请求,反之,则视为无效请求。 如此,上面提到的Nonce值存储成本可能比较大的问题,在结合Timestamp后,可大大降低存储成本,如Timestamp=1min,则仅需存储1min内的请求Nonce值即可,大大减少存储的量级。
另外,每个设计都很难做到完美,或者当前看已经比较完善,但随着技术的发展,会逐渐的暴露一些缺陷,此时,想做一个可持续发展的API签名方案,版本迭代自然少不了,所以,请求内容也可加上版本信息。
Token和API签名方案虽然解决的问题类似,但应用场景略有不同。
API签名适用于后台对后台,不适用于前后端对接。 因为前端场景比较难解决密钥存储问题(且一般面对不同的用户),所以一般都是用户身份一次验证,多次使用(即Token方案),至于用户身份认证可使用其他手段(如密码、短信验证码、图像验证码、邮件验证码等)验证。
具体区别大概如下: