你开放的接口真的就很安全吗,看看有没有做到如下几点

1.请求身份验证

2.请求参数校验

3.请求是否唯一

4.请求次数限制

请求身份验证

基于:为接口调用放分配和(不参与传输,只用于本地接口加密,不能泄露)

基于token身份验证:

1.用户登录提供认证信息(如:账号密码)服务器验证成功后将用户信息保存到token内并设置有效期,再返回token给调用方

2.调用方保存token,并在有效期内重新换取token,保证token是有效的

3.服务器验证token有效性,无效则拦截请求返回错误信息,反之则从token内获取用户信息进行后续操作

请求参数校验

1.校验参数合理性(如:参数类型,参数长度,参数值校验)

2.防止XSS,SQL注入(解决方案:过滤敏感字符或直接返回错误信息)

3.校验参数可靠性是否被篡改(可以将参数以特定格式排列+秘钥组成字符串,在进行MD5或SHA签名)

请求是否唯一

前面第3点解决了请求参数被篡改的隐患接口安全,但是还存在着重复使用请求参数伪造二次请求的隐患

+nonce方案

nonce指唯一的随机字符串 ,用来标识每个被签名的请求。通过为每个请求提供一个唯一的标识符,服务器能够防止请求被多次使用(记录所有用过的nonce以阻止它们被二次使用)。

然而,对服务器来说永久存储所有接收到的nonce的代价是非常大的。可以使用来优化nonce的存储 。

假设允许客户端和服务端最多能存在15分钟的时间差,同时追踪记录在服务端的nonce集合。当有新的请求进入时,首先检查携带的是否在15分钟内,如超出时间范围,则拒绝,然后查询携带的nonce,如存在已有集合,则拒绝。否则接口安全,记录该nonce,并删除集合内时间戳大于15分钟的nonce(可以使用redis的,新增nonce的同时设置它的超时失效时间为15分钟)。

请求次数限制

某些资源我们需要限制用户的请求次数,同时也为了防止非人为操作可能导致系统的崩溃

实现思路如下:

假如我们允许用户每秒钟最多10次请求,超过10次则返回“手速太快了,慢点把。。”

这里我们使用redis辅助我们实现:

以用户IP为key,请求次数为value,有效时间为1秒

用户在每秒的第一次访问的时候,此时我们的redis是没有key为用户ip的数据的(因为失效了,或者第一次请求)所以我们要初始化当前请求用户的ip为为0到redis数据库

当用户在1s内再次发起请求我们就将此ip的请求次数+1,并判断请求次数是否已近>=10

>=10则返回给用户手速太快了!请稍后重试..否则继续执行后续操作

具体实现代码如下:

 Boolean hasIp = redisUtil.hasKey(key);
if (!hasIp) {
            //初始化ip=0
            redisUtil.setEx(key, "0", 1, TimeUnit.SECONDS);
            return true;
 }
 int reqCount = 0;
        String s = redisUtil.get(key);
        if (!StringUtils.isEmpty(s)) {
            reqCount = Integer.parseInt(s);
        }
     
        if (reqCount >= 10) {
            //请求次数大于10限制访问
            throw new ApiRRException("手速太快了!请稍后重试..");
        }
//对请求次数++
        redisUtil.setEx(key, (reqCount + 1) + "", 1, TimeUnit.SECONDS);

如有疑问可在下方留言,我会尽快答复,或者关注公众号 程序员 随时了解新的动态

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注