企业服务内部接口校验方案

>>最全面的Java面试大纲及答案解析(建议收藏)  

企业服务内部接口校验方案

作者:低调的码农

juejin.im/post/6844903877985173511

场景

我们做的产品是 To B 的,那么我们自身会有一个云运营平台的系统,这个系统包含我们所有项目的运营管理数据,在一个月前,我们还不需要想对外提供服务,但是有一天我们数据被其他团队所需要了,需求就来了?

需求:我们要做一个接口认证,用来识别对方服务是啥?

小 A 同学领到任务开始是很开心的,立马做了好几个方案给领导审阅。

方案大爆炸

一、直接在 header 头部或者 url 地址给一个私有 token

约定client的token值为12345678,
那么请求的url地址为:
/remote/getApk?token=12345678

服务端接收到token后,进行匹配判断是否合法token,不合法就退出,合法就是后续操作。 

简单,非常简单,调用方直接拿到这个 token 写入 header 头部或者 url,在服务端拿到后进行简单匹配逻辑来确定调用方是否正确,就完事了,从明面上来讲,这个已经满足需求了,但是新的问题来了?

如果我这个 token 被第三方截取怎么办?

答:上 https,安全

没毛病的,https 是安全,因为在 http 协议的基础上增加一层 SSL/TLS(可以理解为 http 是裸奔,SSL/TLS 是盔甲,遮盖住重要的信息),但是在我们这小门小户要实现全部 https 不太可能,而且 https 对于客户端的调用也不是那么方便,那么接下来又怎么办呢?

二、加上 ip 白名单

其实这里根本不需要加参数,服务端默认就可以获取客户端的 ip,这就保证一点,如果我们 token 被劫持,就算给你发,也没啥用,没错,在很多内部系统中,我们设计接口校验就算基于它来做的,因为这个更简单,基本两边接口完全不需要改东西,写完就可以调,就一个 ip 白名单配置。

那有没有可能这个包被别人劫持,然后进行 ip 代理,然后来请求呢?

三、token 作为加密盐值,cs 作为双方加密认证

前提:

  1. 需要 ip 白名单

  2. 需要为这个调用方产出一个 token(salt)

这里约定就不是token了,使用一个双方约定的密码盐值salt=123456  
  
GET /remote/getApk?md5=043c00e6c7ff021e8cc4d394d3264cb5&sign=md5(043c00e6c7ff021e8cc4d394d3264cb5+123456)  

sign 计算方式:将我们请求的参数按key的正序排序,把里面的值进行字符串连接并且加上salt,再进行一个md5计算,当然可以选择其他hash算法,例如sha1等

这种方案在服务端,我们一样实现这一算法,并且最终校验这个 sign 值是否一样,当然这个方案并不能解决我们刚刚一开始说不安全的问题,因为网络截取是个很平常的事情。

那么有没有办法截取了用不了呢?

答案是肯定的,那我们在 url 地址添加一个请求的时间戳

GET /remote/getApk?t=1561969549&md5=043c00e6c7ff021e8cc4d394d3264cb5&sign=md5(043c00e6c7ff021e8cc4d394d3264cb5+1561969549+123456)

sign 计算方式:将我们请求的参数按key的正序排序,把里面的值进行字符串连接并且加上salt,再进行一个md5计算,当然可以选择其他hash算法,例如sha1等

这里是加一个时间戳作为 sign 的参数,那么可以理解为这个 sign 值是在特定时间内有效,在服务端接收到请求后,可以优先判断时间戳与服务端时间偏移,如果在一分钟之内,那么这个都是可以请求,超过说明这个已经过期了

如果我们对于接口请求严格限制,那么我们每次请求过的 sign 值不能重复,这个涉及到另外话题:

可以简单说一下:我们可以将每个时间戳建立一个桶,每个桶里面装的就是这些 sign 值,这些时间戳的过期时间与服务端判断的过期时间一致(如果 t 字段过期,那么就走不到这一步),就是这么简单哈。

看到这里有同学肯定会问:时间戳不一样咋办,客户端与服务端时间戳肯定会不一样的?

能想到这的同学,真的非常聪明,因为是真的有这个问题出现,当然不是这个场景,只要是时间区间判断的问题,都要考虑双方时间戳的问题

  1. 公司统一使用时间服务器,调用双方同步这个服务器时间。

  2. 客户端不定时同步服务端的时间

总结

其实这个方案设计是仅限于我们企业内部服务相互调用的一个接口设计,刚开始接到任务都会想 jwt oauth2.0 等方案,后来仔细想想,我们压根不需要那么复杂的逻辑来做,因为我们面向的是服务,不是面向独立个体的用户,当然用 jwt 和 oauth2.0 也可以,就是我们接口的请求调用就变成登录、校验、鉴权 等方式了。

谢谢各位同学查阅

精彩推荐

SpringBoot内容聚合
IntelliJ IDEA内容聚合
Mybatis内容聚合


企业服务内部接口校验方案


欢迎长按下图关注公众号后端技术精选

企业服务内部接口校验方案

原文始发于微信公众号(后端技术精选):企业服务内部接口校验方案