接口安全问题java
为开发者分配AccessKey(开发者标识,确保惟一)和SecretKey(用于接口加密,确保不易被穷举,生成算法不易被猜想)。redis
参数签名算法
请求携带参数AccessKey和Sign,只有拥有合法的身份AccessKey和正确的签名Sign才能放行。这样就解决了身份验证和参数篡改问题,即便请求参数被劫持,因为获取不到SecretKey(仅做本地加密使用,不参与网络传输),没法伪造合法的请求。api
虽然解决了请求参数被篡改的隐患,可是还存在着重复使用请求参数伪造二次请求的隐患。数组
timestamp+nonce方案安全
nonce指惟一的随机字符串,用来标识每一个被签名的请求。经过为每一个请求提供一个惟一的标识符,服务器可以防止请求被屡次使用(记录全部用过的nonce以阻止它们被二次使用)。服务器
然而,对服务器来讲永久存储全部接收到的nonce的代价是很是大的。可使用timestamp来优化nonce的存储。markdown
假设容许客户端和服务端最多能存在15分钟的时间差,同时追踪记录在服务端的nonce集合。当有新的请求进入时,首先检查携带的timestamp是否在15分钟内,如超出时间范围,则拒绝,而后查询携带的nonce,如存在已有集合,则拒绝。不然,记录该nonce,并删除集合内时间戳大于15分钟的nonce(可使用redis的expire,新增nonce的同时设置它的超时失效时间为15分钟)。网络
请求接口:api.test.com/test?name=h…dom
客户端
服务端
在APP开放API接口的设计中,因为大多数接口涉及到用户的我的信息以及产品的敏感数据,因此要对这些接口进行身份验证,为了安全起见让用户暴露的明文密码次数越少越好,然而客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时,每次请求都要带上身份验证信息。
与上面开发平台的验证方式相似,为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和全部请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一块儿发送给服务器验证。
这样,即便Token被劫持,对方不知道AppKey和签名算法,就没法伪造请求和篡改参数。再结合上述的重发攻击解决方案,即便请求参数被劫持也没法伪造二次重复请求。
登录和退出请求
登录和退出流程
客户端
服务端
服务端流程