开放API校验签名机制
1现在通用的开放API接口校验机制
现在一些大厂的APP,作为用户的商家来说有可能有一个用户可以对应多个AppKey、secretkey, 对应不同的权限调用。有些权限是有偿服务的。
首先会有一个AppKey,再分配一个私钥secretKey,这时候的AppKey更像一个用户名,secretKey则像一个密码。
举例淘宝卖家,申请淘宝的AppKey 、secretKey,
请求时 https://api.taobao.com/index.html?goods_name=book&price=15.6&sku=12345&AppKey=abcqerr;
校验用户传的参数是否被篡改的做法,首先会把传的参数加上私钥做md5()然后再传到服务器。
$sign = md5(goods_name=book&price=15.6&sku=12345&AppKey=abcqerr&secretKey=abc123);
客户端把签名带上,访问服务器
https://api.taobao.com/index.html?goods_name=book&price=15.6&sku=12345&AppKey=abcqerr&sign=$sign
服务器会根据事先约定好的,按照传递的参数按照key做排序。然后再按客户端做一遍加密后判断签名是否一致。
2 为了防止二次多次请求刷数据的问题
参数防止篡改的问题根据1可以解决。多次请求刷数据的问题怎么解决?
这个做法就是在请求时候带上一个随机数。服务器端记录随机数,如果有二次重刷数据可以根据随机数判断。服务器端记录大量随机数比较费资源,所以加上了一个时效比如15分钟(客户端的时间与服务器的时间有差异,一版不会太大),在时效失效后把记录的随机数删除掉。如果在时效内就做匹配记录,否则就忽略此请求。如果在范围内,就判断存储的随机数是否存在,如果不存在就存储随机数,并接受处理此请求,如果存在就忽略此请求
请求时 https://api.taobao.com/index.html?goods_name=book&price=15.6&sku=12345&AppKey=abcqerr&andom=random()&time=now();
2.1还是按照传递参数加上时间与随机数做个签名
$sign = MD5(goods_name=book&price=15.6&sku=12345&AppKey=abcqerr&random=random()&time=now()&secretKey=abc123);
请求时带上$sign
https://api.taobao.com/index.html?goods_name=book&price=15.6&sku=12345&AppKey=abcqerr&andom=random()&time=now()&sign=$sign;
请求就算完成,但是服务器端存储的请求的随机数删除的问题。
在请求到服务器时,把随机数存储在Redis上,然后设置一个过期时间
例如 SET 123456789 2019-12-12
EXPIRE 123456789 60 //六十秒后过期自动删除此
对用户登录token 也是此流程
用户在登录时 输入账号与密码,请求到服务端,服务器端根据判断是否存在此用户,并生成token传递到用户,每次用户请求时带上token,
在请求的时候还是
带上token值
https://api.taobao.com/index.html?goods_name=book&price=15.6&sku=12345&token=1b2d3e1aa4b&andom=random()&time=now()&sign=$sign;