这辈子没办法做太多事情,所以每一件都要做到精彩绝伦!
People can't do too many things in my life,so everything will be wonderful
需要用到加解密工具类、自定义白名单
接口安全
1 接口安全理论
接口的安全性主要围绕Token、Timestamp(ts)和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看:
Token授权机制:用户使用用户名密码登录后服务器给客户端返回一个Token(通常是UUID或是经过一定规则加密的字符串),并将Token:UserId以键值对的形式存放在缓存服务器(redis)中。服务端接收到请求后进行Token验证,如果Token不存在,说明请求无效。
时间戳ts超时机制:用户每次请求都带上当前时间的时间戳timestamp(ts),服务端接收到timestamp后跟当前时间进行比对,如果时间差大于一定时间(比如5分钟),则认为该请求失效,这个时间要保证足够完成本次请求的同时尽量短,可以减少缓存服务器的压力(见签名机制)。
签名机制:将Token和时间戳加上其他请求参数(也可加上用户个人私钥:盐)进行MD5或SHA-1算法(可根据情况加点盐)加密,加密后的数据为本次请求的签名sign。服务端接收到请求后以同样的算法得到签名,并跟当前的签名进行比对,如果不一样,说明参数被更改过,直接返回错误标识。一样的话,服务端
将该签名存放到缓存服务器(redis)中,超时时间设定为跟时间戳的超时时间一致(这就是为什么要尽量短,二者时间一致可以保证无论在timestamp规定时间内还是外本URL都只能访问一次)同一个签名只能使用一次,如果再次请求发现缓存服务器中已经存在了本次签名,则拒绝服务。
1.1 实现流程
整个流程如下:
1、客户端通过用户名密码登录服务器并获取Token(或token:salt)
2、客户端生成时间戳timestamp(ts),并将timestamp进行AES加密,作为其中一个参数
3、客户端将所有的参数,包括Token和timestamp(ts)按照自己的算法进行排序+salt盐,进行加密得到签名sign
4、将token、timestamp(ts)和sign作为请求时必须携带的参数加在每个请求的URL后边(http://url/request?a=aa&b=bb&token=123×tamp=123&sign=123123123)
5、服务端写一个过滤器对token、timestamp和sign进行验证,只有三个参数都正确且在规定时间内,本次请求才有效(具体实现参考:1.2过滤器实现)
在以上三中机制的保护下,
如果***劫持了请求,并对请求中的参数进行了修改,签名就无法通过;
如果***使用已经劫持的URL进行DOS***,服务器则会因为缓存服务器中已经存在签名而拒绝服务,所以DOS***也是不可能的;
如果***隔一段时间进行一次DOS***(假如这个时间大于签名在缓存服务器中的缓存时长),则会因为时间戳超时而无法完成请求,这就是为什么签名的缓存时长要跟时间戳的超时时长一样。
如果签名算法和用户名密码都暴露了,那就只能:666 了
1.2 过滤器实现
过滤校验流程如下:
1,判断是否是白名单;
2,判断是否是test;(用于开发中测试接口使用;上线时去掉该段代码)
3,获取请求参数requestMap,判断是否有参数;
4,遍历requestMap,校验,并将参数存放在paramMap(按字母顺序排序)中;其中的盐和sign值单独存放,用于后续的加密和比对;
5,获取sign,并判断redis中是否已经存在,存在的话,返回error;
6,获取ts,判断是否可解密和是否超时;否返回:error;
7,获取token,判断token是否可解密和是否于redis中的匹配,否返回:error(也可进行是否登录校验);
8,检查是否有签名值和salt盐;
9,对paramMap拼接成字符串paramString;
10,对paramString+私钥(salt)进行sign加密;和请求参数sign进行比对;不一样,返回:error
转载于:https://blog.51cto.com/wyait/1920134