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

1,520 阅读5分钟

场景

我们做的产品是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也可以,就是我们接口的请求调用就变成登录、校验、鉴权 等方式了。

谢谢各位同学查阅