API漫谈

前言

如何保证API的client来源是真实的,对于API的认证很重要,平时都是按别人的文档和别人通讯也没想过这事,一想还蛮有趣的,下面就让我们来一步步规划一个接口认证的吧。

信息匹对

认证不就是登陆么,用户给我发个身份和密码,我一匹对,正确,通过不久可以了么?

方法

用户发一个 user_id 和 user_key 过来,我们接收后匹对看是否存在。

不足

接口通过HTTP通讯,中间一旦被人窃听,以后就可以拿 user_id 和 user_key 给我们发请求,而我们无法分辨出到底是谁才是真的齐天大圣。看来,不可以把 user_key 这样子发送。

就算认证是可靠的,黑客还是可以拦截住请求,对认证部分不修改但把参数修改了,然后让请求继续发送。例如把你准备给哈利文转账,但是请求在中间被拦截修改后,变成给变色龙转了。

哈希

我们密码存储的时候不是经常md5哈希后保存么,那么我们把 user_key 也哈希一下吧,嗯,正愁不知道拿user_key和谁哈希好,既然说参数会被替换,那么,我们拿 user_key 和 请求参数哈希后的字符串作为 auth_token 传输,而不发送 user_key不就可以了。这样参数也成为认证的一部分,就不会被替换掉了。

做法

把参数按某个规则排好序后,连接成字符串,然后和 user_key 哈希后作为 auth_token,发送。接受端接到请求后,把参数排序后和 user_key 哈希后的字符串和 auth_token 比较。

不足

当参数很少,而 user_key 不复杂的情况下, auto_token 有被碰撞出 user_key的可能

加强版哈希

表示,这种情况对我们这种平时存密码都要多次哈希的孩子来说毫无鸭梨啊,我们可以分别对参数字符串哈希后取一定位数,然后把 user_key 哈希后取一定位数,再把两者连起来哈希作为 auth_token

请求非法 !

什么转了9999次款?黑客大叔表示无法对我们请求下手了,不过他借你某次给他转款的时候拦截到了你的请求,然后不停的伪造一样的请求… 我们可以增加一些策略,防止这种请求重放,例如:在参数里面添加时间戳,最好精确到毫秒,然后把时间戳、user_id和接口方法作为唯一值检验,相同的值只能一次有效。

不足

目前为止,我们能确保请求时持有user_key的user_id发出的,而且不会被修改,不会被重放,user_key也不会暴露,一切都很美好。但是我们的信息是明文的,会照成信息泄露。

加密

可以把内容加密起来传输

方法

HTTPS  
RSA  
利用user_key对整个请求的内容进行异或后重新编码之类的加密

不足

成本高,操作麻烦,目前普通接口通讯一般不会有到这一步的处理。

这是双向的

认证是接口双方都需要做的,不止指用户发给平台,还要包括用户接到平台应答后也应该进行相同的验证

其他手段

ip地址认证
请求有效时间

总之

来源正确,身份正确,内容正确,请求正确,信息安全