V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Jolly23
V2EX  ›  问与答

大家一起来探讨下好的 API 用户密钥设计方案,准备给接口服务加 key,使接口端实现 单用户访问统计/安全防护 等功能

  •  
  •   Jolly23 · 2016-07-22 19:37:36 +08:00 · 5997 次点击
    这是一个创建于 3079 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,本人在学校有一套 API 数据接口服务( python - tornado 写的),提供学校内好多功能,比如成绩查询/考试安排/图书馆借阅/校园网等等等等功能。

    最初设计没加防护,只要学校的 app 开发人员知道我的接口地址再看看文档,带着正确的查询信息,就能获取到返回信息。

    但是随着接口使用者越来越多,访问越来越杂,况且现在接口还提供了学生个人学籍信息的查询(学号+弱口令试一试,建立全校 2/3 学生的个人信息社工库绝对没问题),必须要 api-key 保护了(只限定允许的开发者可以用 api )

    目前我只想出了一种还算高效的解决方案,类似百度 API-Store 那种的,申请了以后给一个 固定的 string 作为 key ,请求 api 的时候加在参数里就可以。

    接口速度是关键,目前每日请求量大概在 5w 次左右,服务器用的 RQ940 放在服务器机房,我的上述方案,只要把我授权出去 api - key - string 写 API 在接口服务的配置文件里就可以了(暂时还不计数,以后可能要放进数据库),这样效率很高,毫不增加多余的响应时间,也算是 api 的一堵墙了吧。

    但是,写固定的 key 也有个弊端,好像它的防护并不是绝对安全的,只要有某些开发人员不小心泄漏了自己 app 使用的 key 或者软件被反搞,让这 key 暴露出去,那还是不能保证 api 不被乱用。

    请大家说说有没有什么更好的解决方案,既可以保证高效,又能比我说的那方案更安全的办法呢?

    10 条回复    2016-07-23 10:16:43 +08:00
    letitbesqzr
        1
    letitbesqzr  
       2016-07-22 20:14:18 +08:00 via iPhone
    参考各大厂商的做法啊,比如限制请求 ip
    Jolly23
        2
    Jolly23  
    OP
       2016-07-22 20:23:37 +08:00
    @letitbesqzr 这个不行,接口服务主要用户是服务器啊,不能限制 ip
    letitbesqzr
        3
    letitbesqzr  
       2016-07-22 20:46:08 +08:00
    @Jolly23 怎么不能了... 服务器一般就一个网段啊... 让用户自己设置自己的 ip 白名单... 支持范围
    free9fw
        4
    free9fw  
       2016-07-22 20:48:38 +08:00
    学微信呀,主动式 token+expire
    Jolly23
        5
    Jolly23  
    OP
       2016-07-22 21:46:33 +08:00 via iPhone
    @free9fw 这个值得研究下,挺想搞搞 access_token ,又担心下游开发者不会用
    ijimmy
        6
    ijimmy  
       2016-07-22 22:47:00 +08:00 via iPhone
    支付宝的接口文档,多看看有惊喜
    klesh
        7
    klesh  
       2016-07-22 22:51:28 +08:00   ❤️ 6
    直接传 key 简直就是多此一举啊,随便监听一下网络就能把你的 key 盗走。
    最简单的方式是使用签名,各大开放平台都是这样做的,性能好,安全性不错。

    签名基本原理是通过 key/secret 的实现:
    1, 服务器负责为每个客户端生成一对 key/secret ( key/secret 没有任何关系,不能相互推算),保存,并告知客户端。
    2, 当客户端调用 api 时,根据某种规则将所有请求参数串联起来并用 secret 生成签名 sign 。
    3, 将 sign 和 key 一起放进请求参数对服务器进行调用。(注意 secret 不要传)
    4, 服务端收到请求,根据 key 去查 secret ,然后用同样的算法,验证签名。
    5, 为避免重放攻击,可加上 timestamp 参数,指明客户端调用的时间。服务端在验证请求时若 timestamp 超过允许误差则直接返回错误。

    以上,即使第三方知道了你的算法, key 等信息,由于无法捕获到 secret ,也无法推算,因此是安全的。最好是把 api 布署成 https 的。
    realityone
        8
    realityone  
       2016-07-22 23:53:55 +08:00 via iPhone
    客户端证书,套 nginx 加 header 收集频率信息,取消一个人的权限就直接吊销他证书
    Jolly23
        9
    Jolly23  
    OP
       2016-07-23 00:10:30 +08:00
    @klesh 非常感谢,我先想想这个
    xiaoshangmin
        10
    xiaoshangmin  
       2016-07-23 10:16:43 +08:00 via iPhone
    我模仿微信 access_token 也搞过一套接口
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5500 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 08:54 · PVG 16:54 · LAX 00:54 · JFK 03:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.