前后端分离如何保证后端接口的安全性

为什么要保证后端接口安全?

对于前后端分离的项目来说,后端接口层其实是完全独立的。这意味着他完全暴露在了互联网中,有可能被滥用,被攻击,被爬。所以把接口安全做好是非常有必要的。一般来说接口安全主要指这几方面:

  • 不帮别人干活!比如你有一个接口是查询ip所在的具体位置,不做任何安全设置极有可能变为公共接口。
  • 防止数据被爬虫获取
  • 请求参数不被别人篡改
  • 防止cc攻击
  • 防止系统入侵

保护接口安全的几种方案

1.跨域限制

跨域限制主要应用在web环境下,由浏览器进行执行。为什么需要限制跨域呢?

比如你用做了一个前后端分离项目(后端地址:api.abc.com,前端地址:front.abc.com),该项目的功能是获取最新的天气信息。天气信息是你的独家资源,所以价值很高。现在张三也想做一个同类型的网站,无奈他并没有信息源。但是他发现了你这个项目。于是他自己马上用vue写了一个前端(部署在123.com),再套用你的后端接口。那么他付出了极小的成本就把这个项目给做成了。你当然不干,因为他盗取了你的数据。那么我们怎么限制张三无法调用你的后端接口呢?

其实默认情况下,浏览器是以及帮你限制了的。但是目前很多的后端开发都会将跨域设置为*,这意味着允许任何网站调用该接口。

1
Access-control-allow-origin: *

所以我们必须要规范这个http响应头,将他设置为指定的域,比如:

1
Access-Control-Allow-Origin: https://front.abc.com

这样浏览器就会允许api.abc.com的后端接口被前端front.abc.com所调用。更多跨域的相关知识可以查看MDN

2.用户指纹信息

一般来说有些接口会限制只允许特定人群访问。比如修改用户信息接口,必须是当前登录了的用户才能够调用。游客是不能调用修改用户信息接口的。对于这种情况我们一般都会使用网关进行鉴权。他的大概实现路径是这样:

  • 使用账号密码进行登录,登录成功的同时,随机生成一个accessToken,并且将用户权限查询出来存放到redis中(以accessTokenkey)。
  • 随后的接口调用都会将这个accessToken带入到http头中传给网关。
  • 网关会拿accesTokenreids换取用户权限,然后判断该用户是否有权访问此接口。

3.防止接口参数被篡改和重放

仅仅做到第二步还是不够,用户有可能会修改接口中的参数。比如有一个根据id删除帖子的接口,注意这里的id是自增的。张三是你的同行竞争对手,他获取到accessToken之后,写了一段js脚本开始从0到1000000遍历id调用根据id删除帖子的接口。那么毫无疑问,你的系统中的帖子会被张三全部删光。为了防止这种可怕的事情发生,我们不应该允许用户随意修改参数。一般我们会使用对称加密摘要的方式来解决这个问题。

首先前端和后端肯定需要约定一个加密签名的算法,同时还要使用同样的密钥(对称加密)。

这里的前端加密并不是只将所有的接口参数变成密文,因为这可能就不太方便开发调试了。我们前端主要能产生一个签名就行了,如果后端通过同样的方式签名发现和前端的不一致,那么就认为这次是非法请求。具体签名我们可以使用下面的算法:

1
md5(uli+query参数(key按字母排序后)+body参数+当前时间(格林威治时间数值)+密钥)

至于防止重放的话,也是需要做的一个事情。不然充值100元的接口重复调用10次你能接受吗?要做到防止重复必须要利用当前时间这个参数。这个参数用做生成签名也要传到网关来,假设签名校验正确那么就拿传过来的当前时间来和你服务器本地时间进行判断,如果误差超过5分钟那么就认定非法。

4.多租户保证接口数据安全

对称加密肯定是不够足够安全的,因为密钥前端也存着一份,无论你怎么加密、打包只要破解的人够有耐心,肯定是可以得到密钥的。那么我们没有办法解决了吗?张三改变一下接口参数就能访问王五的数据吗?终极办法是从sql处进行拦截,因为最终的增删改查都是靠sql完成的。终极方案如下:

  • 接到http请求后,将accessToken对应的用户标识(比如userId)设置到当前http线程的ThreadLocal当中。
  • 执行sql时,使用druid解析sql,将sql中的用户标识的值提取出来
  • sql中的用户标识和当前http线程的ThreadLocal当中用户标识比较
  • 如果不一致,说明是非法访问其他数据。

5.限流防止接口被cc攻击

这里主要将的是接口限流。假设一个耗时接口被暴露出来,让一个黑客频繁调用可能你的系统就直接崩了。此时我们需要使用一些接口限流的方法。常用的方法有:

  • RedisRateLimiter,主要是依赖redis做一个分布式限流。
  • Sentinel,这个是阿里巴巴出品的开源限流工具,能够适用的场景更多。

6.使用WAF网站应用防火墙

千防万防漏洞难防!很多0day漏洞一旦公布于世就会有一大片程序员挑灯夜战。相信大家对strust2、fastjson等开源框架的漏洞不陌生了吧?太多漏洞让我们防不胜防,有没有办法有一个一劳永逸的办法呢?只要你肯出钱还是有人替你解决的。这个就是WAF网站应用防火墙。他不但可以防止平常的0day漏洞,还可以帮你阻挡SQL注入、XSS跨站、Webshell上传、cc攻击等等。他的大概原理是让你把域名解析到他的服务器,然后确定这个http请求是安全的,再转发到你的服务器。直白的说就是反向代理,只不过在转发流量的时候帮你过滤了高危请求。

网站应用防火墙

一般WAF的价格比较贵,只有中大型企业才用得起。拿腾讯云举例基础套餐1年大概要3万块钱,你受得了吗?

image-20201202221614921

原文链接:https://www.jdkdownload.com/api_safety.html