【JAVA】OpenFegin 实现接口参数签名认证(一)

3,388 阅读6分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

我们在日常开发中,常常会对接一些三方sdkapi,而对接这些sdk就必然会遇到参数签名认证的问题,下面我将会用两篇文章来讲解 什么是接口参数签名认证、以及 OpenFeign 如何实现接口参数签名认证。下面让我们开始吧

为啥接口要使用参数签名

有些同学可能还没有接触过参数签名校验,下面我们将会详讲一下出现的场景,以及为啥需要 😍。

我们在使用三方sdk的时候,一般是不需要进行登录获取认证信息的。为啥呢?如果使用登录的话,过程繁琐,而且存在维护认证信息困难的问题。所以我们可以发现,一般的三方 开放sdkapi 接口,都会提供给我们一个 appkey(有的叫 appid,反正是同一种东西) 和一个 appsecret 来代替登录。有的小伙伴就会有疑问了,这和参数签名校验有啥关系呢?🤪 别慌,我们慢慢道来。

image.png

首先,我们思考一下,只有一个 appkeyappsecret 我们怎么实现接口身份认证呢?同学们可以先闭目思考一下。是直接把 appkeyappsecret 直接当成参数明文传过去吗?🤓,嘻嘻,应该没有同学这么想的吧。。。

image.png

我们明确一点,appkey 表明你是谁, appsecret 表明你就是真的你,这两个值 appkeyappsecret 是必然需要包含到请求信息里面的。要让别人找到你,appkey 肯定是需要直接给到对方的(ps: 可以明文,也可以通过加密的方式,只要协商好,啥都不是事儿),appsecret 则需要用某种 “加密” 的方式隐藏在参数里面,在认证的时候,比对身份信息是否匹配,匹配 ok 通过,匹配 错误 ,那就拜拜。这时候我们欠缺的就是某种 “加密” 的方式了。咱也不卖关子,就直接说说这个带引号的 “加密” 通常是怎么做的吧。

20180129234948_UPGeXa.gif

  1. 一般的三方开放sdkapi都会要求带上至少三个参数,appkeysigntimestamp,这三个参数呢,可能各有各的叫法,首先第一个 appkey ,有的三方sdk叫 appid,这个没有什么好讲的,这个是用来表明身份的。接着是第三个参数 timestamp (这里仅仅是个代称,代指除 appkeysign 以外必要的参数) ,这个就比较花里胡哨了,可能每个三方sdk的名字都不一样,普遍一点,可能叫 timestampnoncesaltrand 等等,也可能是几个的组合,它的作用主要是给第二个参数 sign 的生成做夹杂参数的,作用我们和第二个参数 sign 一起讲,现在我们就来讲讲参数签名最核心的参数 sign

  2. sign 一般由哈希算法生成,原串一般由 appkey + appsecret + 请求参数或者请求体 + timestamp 拼接而成(这个拼接规则就相当于上段中所说的 “加密” 方式),经过我们常见的哈希算法 MD5 或者 SHA-1 处理之后,得到我们最终的 sign 。聪明的小伙伴可能已经明白为啥要这样做了,当我们在后端接收参数时,通过 appkey 获取对应用户的 appsecret,如果没有找到appsecret,肯定直接认证失败再按照约定好的 “加密” 方式拼接好各个参数,再以相同的哈希算法生成一个 sign,最终和参数上带的参数 sign 比对,如果一致,就认证通过。这里还需要注意的一个点 请求参数或者请求体 必须是有序的,保证接口文档声明的一致,这样才能保证后端接收到的 请求参数或者请求体 一致,这样生成的 sign 才不会出现意料之外的差错。

  3. 有的同学可能会有这样的疑问?上一段落中的第三个参数 timestamp 有啥用,如果去掉这个参数,后端肯定跑的一样好。有这个想法很不错,是个机智的boy,但是这样会有一个问题,如果这个请求地址被其他人抓到,其他人就可以不断的访问这个 请求地址 获得资源,后端对其的校验结果,永远是通过的,所以第三个参数 timestamp 必不可少。

  4. 对于不同的sdkapi提供商,每个的实现方式和安全强度也不一致,如果安全强度低,可能第三个参数 timestamp 仅仅需要一个唯一的随机值 nonce 即可,后端仅仅需要判断一下这个 nonce 有没有被使用过,如果被使用过则判定不通过,以此来保证每次请求都是唯一的。而有的安全强度高,第三个参数 timestamp 则可能由两个参数或者更多组成。咋们来个比较常见的,第三个参数 timestamp 由一个 timestamp 时间戳,一个 nonce 随机值组成,后端在校验时,不仅仅会判断 nonce 有没有被使用过,同时还会校验这个 timestamp 与服务器时间相差多少,如果相差大于 某个值 ,则也会判定不通过。比如后端这个值设定为 5秒 ,那么每一个请求的时间戳与服务器时间相比较不能超过 5秒 ,间隔超过 5秒 的请求会被认定为重放攻击或者错误的请求,这样极大的保证了接口的安全性。懂了这个原理的话,这第三个参数 timestamp 就有了 N种 组合的可能。

带点后端的思考,对于我这个干了几年的 后端菜菜鸟 来说,这第三个参数 timestampN种 组合中,带时间戳的肯定是比较好的,如果要保证请求的唯一性,那么就需要有个地方来保存这些已经请求过的第三个参数 timestamp ,如果请求量大时间长,维护这个东西肯定就开始伤脑筋了。而带时间戳的,就有了过期时间,如果超过设定的值,直接丢掉即可,减少维护和存储的成本😜

image.png

总结一下

我们总结一下上面三个参数的作用

  1. 保证每次请求唯一
  2. 防止参数被篡改
  3. 保证请求合法,来自认证用户

这也就是我们为啥要参数签名校验的原因咯😵

本篇文章到这儿就结束了,碍于时间问题,第二篇 OpenFeign 如何实现接口参数签名认证 咋们明天继续👻,谢谢大家的支持与鼓励。


如果文章对您有帮助的话,欢迎 点赞 、 评论 、 关注 、 收藏 、 分享 ,您的支持是我码字的动力,万分感谢!!!🌈

如果文章内容出现错误的地方,欢迎指正,交流,谢谢😘

参考链接