API接口之安全篇
APP、前后端分离项目都采用API接口形式与服务器进行数据通信,传输的数据被偷窥、被抓包、被伪造时有发生,那么如何设计一套比较安全的API接口方案呢?
一般的解决方案如下:
1、Token授权认证,防止未授权用户获取数据;
2、时间戳超时机制;
3、URL签名,防止请求参数被篡改;
4、防重放,防止接口被第二次请求,防采集;
5、采用HTTPS通信协议,防止数据明文传输;
一、Token授权认证
HTTP协议是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的,但是对我们有权限访问限制的模块而言,它是需要有状态管理的,以便服务端能够准确的知道HTTP请求是哪个用户发起的,从而判断他是否有权限继续这个请求。
Token的设计方案是用户在客户端使用用户名和密码登录后,服务器会给客户端返回一个Token,并将Token以键值对的形式存放在缓存(一般是Redis)中,后续客户端对需要授权模块的所有操作都要带上这个Token,服务器端接收到请求后进行Token验证,如果Token存在,说明是授权的请求。
Token生成的设计要求:
1、应用内一定要唯一,否则会出现授权混乱,A用户看到了B用户的数据;
2、每次生成的Token一定要不一样,防止被记录,授权永久有效;
3、一般Token对应的是Redis的key,value存放的是这个用户相关缓存信息,比如:用户的id;
4、要设置Token的过期时间,过期后需要客户端重新登录,获取新的Token,如果Token有效期设置较短,会反复需要用户登录,体验比较差,我们一般采用Token过期后,客户端静默登录的方式,当客户端收到Token过期后,客户端用本地保存的用户名和密码在后台静默登录来获取新的Token,还有一种是单独出一个刷新Token的接口,但是一定要注意刷新机制和安全问题;
根据上面的设计方案要求,我们很容易得到Token=md5(用户ID+登录的时间戳+服务器端秘钥)这种方式来获得Token,因为用户ID是应用内唯一的,登录的时间戳保证每次登录的时候都不一样,服务器端秘钥是配置在服务器端参与加密的字符串(即:盐),目的是提高Token加密的破解难度,注意一定不要泄漏;
二、时间戳超时机制
客户端每次请求接口都带上当前时间的时间戳timestamp,服务端接收到timestamp后跟当前时间进行比对,如果时间差大于一定时间(比如:1分钟),则认为该请求失效。时间戳超时机制是防御DOS攻击的有效手段。
例:http://url/getInfo?id=1&timetamp=1559396263
三、URL签名
写过支付宝或微信支付对接的同学肯定对URL签名不陌生,我们只需要将原本发送给server端的明文参数做一下签名,然后在server端用相同的算法再做一次签名,对比两次签名就可以确保对应明文的参数有没有被中间人篡改过。
首先我们需要分配给客户端一个私钥用于URL签名加密,一般的签名算法如下:
1、首先对通信的参数按key进行字母排序放入数组中(一般请求的接口地址也要参与排序和签名,那么需要额外添加url=http://url/getInfo这个参数);
2、对排序完的数组键值对用&进行连接,形成用于加密的参数字符串;
3、在加密的参数字符串前面或者后面加上私钥,然后用md5进行加密,得到sign,然后随着请求接口一起传给服务器。
例如:
http://url/getInfo?id=1&timetamp=1559396263&sign=e10adc3949ba59abbe56e057f20f883e
服务器端接收到请求后,用同样的算法获得服务器的sign,对比客户端的sign是否一致,如果一致请求有效;
注意:对于客户端的私钥一定要妥善处理好,不能被非法者拿到,如果针对于H5的项目,H5保存私钥是个问题,目前没有更好的方法,也是一致困扰我的问题,如果大家有更好的方法可以留言一起探讨。
四、防重放
客户端第一次访问时,将签名sign存放到服务器的Redis中,超时时间设定为跟时间戳的超时时间一致,二者时间一致可以保证无论在timestamp限定时间内还是外 URL都只能访问一次,如果被非法者截获,使用同一个URL再次访问,如果发现缓存服务器中已经存在了本次签名,则拒绝服务。如果在缓存中的签名失效的情况下,有人使用同一个URL再次访问,则会被时间戳超时机制拦截,这就是为什么要求sign的超时时间要设定为跟时间戳的超时时间一致。拒绝重复调用机制确保URL被别人截获了也无法使用(如抓取数据)。
以上方案流程如下:
1、客户端通过用户名密码登录服务器并获取Token;
2、客户端生成时间戳timestamp,并将timestamp作为其中一个参数;
3、客户端将所有的参数,包括Token和timestamp按照自己的签名算法进行排序加密得到签名sign
4、将token、timestamp和sign作为请求时必须携带的参数加在每个请求的URL后边
例:
http://url/request?token=h40adc3949bafjhbbe56e027f20f583a&timetamp=1559396263&sign=e10adc3949ba59abbe56e057f20f883e
5、服务端对token、timestamp和sign进行验证,只有在token有效、timestamp未超时、缓存服务器中不存在sign三种情况同时满足,本次请求才有效;
五、采用HTTPS通信协议
众所周知HTTP协议是以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了客户端和服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为客户端和服务器之间的通信加密。
HTTPS也不是绝对安全的,如下图所示为中间人劫持攻击,中间人可以获取到客户端与服务器之间所有的通信内容。
中间人截取客户端发送给服务器的请求,然后伪装成客户端与服务器进行通信;将服务器返回给客户端的内容发送给客户端,伪装成服务器与客户端进行通信。
通过这样的手段,便可以获取客户端和服务器之间通信的所有内容。
使用中间人攻击手段,必须要让客户端信任中间人的证书,如果客户端不信任,则这种攻击手段也无法发挥作用。
2 针对安全性要求一般的app,可采用通过校验域名,证书有效性、证书关键信息及证书链的方式;
总结:所有的安全措施都用上的话有时候难免太过复杂,在实际项目中需要根据自身情况作出取舍,比如可以只使用签名机制就可以保证信息不会被篡改,或者定向提供服务的时候只用Token机制就可以了,如何取舍,全看项目实际情况和对接口安全性的要求。
API接口之安全篇的更多相关文章
- appium API接口
appium API接口 标签(空格分隔): appium常用api 1.contexts contexts(self) 返回当前会话的上下文,使用可以识别H5页面的控件: driver.contex ...
- List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac
List多个字段标识过滤 class Program{ public static void Main(string[] args) { List<T> list = new List& ...
- 免费天气预报API接口
一.中国气象局(http://www.weather.com.cn) 1.实时接口 http://mobile.weather.com.cn/data/sk/101010100.html http:/ ...
- Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回
前言 现在我们做项目基本上中大型项目都是选择前后端分离,前后端分离已经成了一个趋势了,所以总这样·我们就要和前端约定统一的api 接口返回json 格式, 这样我们需要封装一个统一通用全局 模版api ...
- 记一次Hvv中遇到的API接口泄露而引起的一系列漏洞
引言 最近朋友跟我一起把之前废弃的公众号做起来了,更名为鹿鸣安全团队,后面陆续会更新个人笔记,有趣的渗透经历,内网渗透相关话题等,欢迎大家关注 前言 Hvv中的一个很有趣的漏洞挖掘过程,从一个简单的A ...
- 基于Node和Electron开发了轻量版API接口请求调试工具——Post-Tool
Electron 是一个使用 JavaScript.HTML 和 CSS 构建桌面应用程序的框架. 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 Java ...
- APISpace 成语大全API接口 免费好用
成语有一个很大一部分是从古代相承沿用下来的,在用词方面往往不同于现代汉语,它代表一个故事或者典故.成语又是一种现成的话,跟习用语.谚语相近,但是也略有区别.成语是中华文化中的一颗璀璨的明珠. 成语 ...
- 干货来袭-整套完整安全的API接口解决方案
在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...
- 12306官方火车票Api接口
2017,现在已进入春运期间,真的是一票难求,深有体会.各种购票抢票软件应运而生,也有购买加速包提高抢票几率,可以理解为变相的黄牛.对于技术人员,虽然写一个抢票软件还是比较难的,但是还是简单看看123 ...
随机推荐
- koa 路由、视图模块化(二)
1.项目目录 2.路由 根目录/routes/index.js -- 首页 const router = require('koa-router')(); router.get('/', async ...
- C# 中使用RegisterShellHookWindow Hook窗体创建
前言:最近在写一个桌面程序时需要全局HOOK 窗体的创建,但是在.net中SetWindowsHookEx()只可实现键盘鼠标的全局钩子,其余的全局钩子都需要使用DLL.难道就没有解决办法了么?经过长 ...
- 2.ibatis执行流程解析
以下仅为个人理解,如有问题,欢迎指正
- JavaScript this的使用
当作用域不同时,我们可以将this暂时性的保存下来. 例如: _this = this.
- shell中变量计算
year=44 1.let,不需要$引用变量 let m=year+3 echo $m 2.(()) m=$((year+3)) 3.[ ],注意两边一定要有空格 m=$[ year+3 ] 4. ...
- spring boot系列(三)spring boot 配置spring data jpa
数据库使用MySQL,ORM使用spring data jpa 1 因此需要再pom.xml文件中添加相应jar包.如下: <!-- 引入jap --> <dependency> ...
- k8s设置集群角色
查看所有的node节点 [root@test1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION test1 Ready <none> ...
- k8s1.11.0安装、一个master、一个node、查看node名称是主机名、node是扩容进来的、带cadvisor监控服务
一个master.一个node.查看node节点是主机名 # 安装顺序:先在test1 上安装完必要组件后,就开始在 test2 上单独安装node组件,实现node功能,再返回来配置test1加入集 ...
- VS2015服务器资源管理器连接Mysql数据库
下载安装文件mysql-for-visualstudio-1.2.3.msi 下载成功后执行安装,选择change-->选择Custom安装成功后,发现vs中没有效果. 注意这里再次执行安装文件 ...
- 【.NET】Browser Link: Failed to deserialize JSON in Browser Link call
问题 VS2013中调试程序发现,在浏览器控制台输出如下截图代码: