Java生鲜电商平台-安全设计与架构算法
说明:Java开源生鲜电商平台是一个B2B的生鲜电商平台,因为是APP的一种模式,因此安全方面通常会思考如下几个维度:json
1.数据安全。api
2.传输安全。数组
App与服务器的通讯接口如何设计得好,须要考虑的地方挺多的,在此根据个人一些经验作一些总结分享,旨在抛砖引玉。安全
如今,大部分App的接口都采用RESTful架构,RESTFul最重要的一个设计原则就是,客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时,每次请求都要带上身份验证信息。实现上,大部分都采用token的认证方式,通常流程是:服务器
然而,此种验证方式存在一个安全性问题:当登陆接口被劫持时,黑客就获取到了用户密码和token,后续则能够对该用户作任何事情了。用户只有修改密码才能夺回控制权。微信
如何优化呢?第一种解决方案是采用HTTPS。HTTPS在HTTP的基础上添加了SSL安全协议,自动对数据进行了压缩加密,在必定程序能够防止监听、防止劫持、防止重发,安全性能够提升不少。不过,SSL也不是绝对安全的,也存在被劫持的可能。另外,服务器对HTTPS的配置相对有点复杂,还须要到CA申请证书,并且通常仍是收费的。并且,HTTPS效率也比较低。通常,只有安全要求比较高的系统才会采用HTTPS,好比银行。而大部分对安全要求没那么高的App仍是采用HTTP的方式。数据结构
咱们目前的作法是给每一个接口都添加签名。给客户端分配一个密钥,每次请求接口时,将密钥和全部参数组合成源串,根据签名算法生成签名值,发送请求时将签名一块儿发送给服务器验证。相似的实现可参考OAuth1.0的签名算法。这样,黑客不知道密钥,不知道签名算法,就算拦截到登陆接口,后续请求也没法成功操做。不过,由于签名算法比较麻烦,并且容易出错,只适合对内的接口。若是大家的接口属于开放的API,则不太适合这种签名认证的方式了,建议仍是使用OAuth2.0的认证机制。架构
咱们也给每一个端分配一个appKey,好比Android、iOS、微信三端,每一个端分别分配一个appKey和一个密钥。没有传appKey的请求将报错,传错了appKey的请求也将报错。这样,安全性方面又加多了一层防护,同时也方便对不一样端作一些不一样的处理策略。app
另外,如今愈来愈多App取消了密码登陆,而采用手机号+短信验证码的登陆方式,我在当前的电商项目中也采用了这种登陆方式。这种登陆方式有几种好处:
接口的数据通常都采用JSON格式进行传输,不过,须要注意的是,JSON的值只有六种数据类型:
因此,传输的数据类型不能超过这六种数据类型。之前,咱们曾经试过传输Date类型,它会转为相似于"2016年1月7日 09时17分42秒 GMT+08:00"这样的字符串,这在转换时会产生问题,不一样的解析库解析方式可能不一样,有的可能会转乱,有的可能直接异常了。要避免出错,必须作特殊处理,本身手动去作解析。为了根除这种问题,最好的解决方案是用毫秒数表示日期。
另外,之前的项目中还出现过字符串的"true"和"false",或者字符串的数字,甚至还出现过字符串的"null",致使解析错误,尤为是"null",致使App奔溃,后来查了很久才查出来是该问题致使的。这都是由于服务端对数据没处理好,致使有些数据转为了字符串。因此,在客户端,也不能彻底信任服务端传回的数据都是对的,须要对全部异常状况都作相应处理。
服务器返回的数据结构,通常为:
{
"code":"200", "message": "请求成功", "Object": { key1: value1, key2: value2, ... } }
不一样错误须要定义不一样的返回码,属于客户端的错误和服务端的错误也要区分,好比1XX表示客户端的错误,2XX表示服务端的错误。这里举几个例子:
错误信息通常有两种用途:一是客户端开发人员调试时看具体是什么错误;二是做为App错误提示直接展现给用户看。主要仍是做为App错误提示,直接展现给用户看的。因此,大部分都是简短的提示信息。
data字段只在请求成功时才会有数据返回的。数据类型限定为对象或数组,当请求须要的数据为单个对象时则传回对象,当请求须要的数据是列表时,则为某个对象的数组。这里须要注意的就是,不要将data传入字符串或数字,即便请求须要的数据只有一个,好比token,那返回的data应该为:
// 正确 data: { token: 123456 } // 错误 data: 123456
接口不可能一成不变,在不停迭代中,总会发生变化。接口的变化通常会有几种:
为了适应这些变化,必须得作接口版本的设计。实现上,通常有两种作法:
大部分状况下会采用第一种方式,当某一个接口有变更时,在这个接口上叠加版本号,并兼容旧版本。App的新版本开发传参时则将传入新版本的version。
若是整个接口系统的根基都发生变更的话,好比微博API,从OAuth1.0升级到OAuth2.0,整个API都进行了升级。
有时候,一个接口的变更还会影响到其余接口,但作的时候不必定能发现。所以,最好还要有一套完善的测试机制保证每次接口变动都能测试到全部相关层面。
关于接口安全的设计以及架构,以及密码学安全方面等等,我这只是给了一个实际的例子,告诉你们,我是这么作的,有问题欢迎留言。