App全部数据都来源于服务器,App和服务器交互广泛是采用http请求接口的方式,那么在搭建和维护一个后端Api项目时候须要注意哪些问题呢?nginx
数据保护作的好很差,有两个原则来验证:
第一,能够控制让谁来读取数据,
对于任何一个Api项目其实就是只容许产品App自己访问,这就须要用密文传输请求数据,作到即便被人用抓包工具抓到请求数据也没有办法解析出参数的意义。
把安全作到更近一步,能够在加密以前引入timestamp参数,在服务端经过比较timestamp和当前时间戳能够作到对于抓取到的连接也不能重复调用。
密文的安全性取决于参数的加密方式,使用对称加密、非对称加密或者二者结合取决于团队本身的选择,固然若是接口域名已经配了证书支持https,就不用本身写代码来作这些事情了。
若是密文传输已经作到绝对安全不可破解,那就安全了吗?固然不是,你要相信安全永远是相对的。试想一下若是App源码被反编译成功,那他就能够按照代码逻辑去拼出正常的请求?另一般业务除了有app以外也会有使用相同接口的h5版,任意一个开发者经过浏览器的调试模式很容易能分析出请求的Url以及相关参数。对于这两种状况怎么办呢?sql
第二,对于能够获取数据的端,也能够控制其能够获取哪些数据
既然客户端不能作到彻底可靠,那就让服务端多承担一些任务,在app启动时或者用户登陆时服务端先向每一个客户端分发一个有固定有效期的secret,而且在服务端数据库库中存储客户端惟一标示或者uid和secret的对应关系,以后每次客户端调用都要用secret对于参数组合进行一次签名,而且确保参数包含uid,服务端接收到请求后根据uid找出对应的secret,而后按照和客户端相同的签名方式得出签名,进而和客户端传过来的签名进行比较。
由于secret是服务端分发的,即便破解了源码,再即便从本地解析出了保存的secret,那也只能获取这个secret对应的数据,再加上secret自己会有更新机制,这就使得经过破解接口来抓取大量数据变得大大的困难。数据库
可是对于向第三方开放的api接口状况就不太同样,它不存在密文传输的问题,大致思路也是使用secret进行签名认证,只是分发secret的方式不同,它是经过合做的方式,api提供商会给使用方分发一个key和一个secret,二者能够当成一个键值对。调用方每次调用时用secret进行参数的签名,参数包含key,服务端接收到请求,根据key参数取出secret,而后进行相同方式的签名,而且和客户端传入的签名进行对比来完成验证。后端
总结一下数据保护的技术点:api
一些经常使用的安全问题都要考虑到,而且在api项目框架底层进行防范,例如xss攻击、sql注入问题、单用户或者单ip的访问频率控制来进行防cc攻击。数组
互联网产品版本迭代很快,对于同一个功能新旧版本在参数或者返回值上会有差异。对于这种问题会有不一样观点的解决方案,一种方案是在url中加入版本信息,好比http://api.demo.com/v1/test , 每一个版本对应一个Action,具体的业务逻辑不要写在Action层,要封装到下面的逻辑层,这样Action只须要在主业务的基础上根据需求进行扩展。另一种观点是,这样代码重复度过高,会有大量的action文件,一个功能只提供一个惟一的url,可是要带上一个表示版本的参数,在代码框架中只有一个action,对于新旧版本的细小差异可使用参数默认值等兼容方式进行处理,对于比较大的改动就经过逻辑判断语句进行不一样处理便可。
另外比较重要的一点是,在设计之初要对业务进行足够的抽象化,让设计自己能尽可能支持变化,好比之后此接口是否会增长某个分类属性,返回结果的格式是否再多包装一层就能够应对万一后面版本要增长另外一块数据。
固然不可能同时维护全部旧的版本,要作到能够检测每一个版本的使用状况,并且能够根据版本使客户端强制升级。对于功能的修改,同时维护旧版本是一件特别麻烦的事情,甚至有些状况不得不强制升级全部版本。
总结一下就是:浏览器
很容易理解,服务端不用发版,服务端没有处理不了的问题,很简单一个例子:用户登陆功能,会有"密码错误","尚未注册"等各类异常状况的提示。那具体的文案是在客户端定义,仍是从服务端直接返回给客户端比较好呢,显然是后者。由于之后提示语内容要作修改的话,放在服务端就能够很简单进行处理,放在客户端只能从新发版。安全
A、B两个功能都须要获取用户信息,二者调用同一个接口,可是A只须要获取用户名和电话,就没有必要把其它信息返回给A。服务器
nginx公众号也会推送好文,主要聊聊后端技术,扫描或者搜索nginx便可添加。
![]()