最近在作API的权限设计这一块,作一次权限设计的总结。算法
1. 假设咱们须要访问的API接口是这样的:http://xxxx.com/openapi/v1/get/user/?key=xxxxx&sign=sadasdas×tamp=2013-03-05 10:14:00&c=c&a=a&d=d数据库
2. 接口调用的控制器:openapi/v1/get/user/api
3. 步骤一:做为服务端,首先要检查参数是否正确:key (用户的key) ;sign(加密的签名串) ;timestamp (请求的时间,服务端对请求有时间生效),这些参数若是有一个参数没传递,确定返回参数不正确的结果。安全
4. 步骤二:参数若是都传递正确,这个时候须要检查API的白名单权限,API也就是(openapi/v1/get/user/)是否存在在咱们的数据库中,通常会有一张API的数据表,若是调用的API不在咱们的数据库白名单中或者这个API已经关闭访问了,那么要返回禁止访问的结果。加密
5. 步骤三: 若是API在白名单中,那么如今就要检查用户的KEY是否正确了,服务端会有一张用户权限表,这个数据表主要用来记录用户的key secret(密钥) 以及API权限列表,检查这个用户对访问的API(openapi/v1/get/user/)是否有权限,若是有权限则经过,没权限则关闭。设计
6. 步骤四: 若是用户权限经过,这个时候就到了最重要的一步,SIGN签名的验证。排序
签名算法:接口
加密方式 md5(POST参数(升序排序,除key sign参数除外) + 用户密钥) md5
注意:加密的时候,须要将timestamp带上,防止客户端篡改。get
客户端,将本身须要传递的参数进行升序排序,而后加上本身key对应的密钥(密钥在服务端数据库中有一份保存,这个是不能对外公开的)进行MD5加密,经过参数sign传递到服务端。
服务端拿到sign值后,对传递过来的参数也进行一样的算法排序,并通过用户的key查询获得密钥,而后进行一次加密算法,获得的服务端的sign和客户端传递过来的sign进行比较,若是相同则表示是能够经过的,若是中途有人篡改数据等,那么最终加密出来的sign就是不一致的,这样保证了用户传递数据的可靠性和安全性。
7. 步骤五:检查时间戳时间,比较客户端时间和服务端时间是否在10分钟以内,若是10分钟以外了,那么返回超时的提示,这样能保证调用过的接口数据能在必定时间内销毁掉。
8. 步骤六:调用相应逻辑