接口的设计
App 和服务器的接口要设计好,得同时考虑安全、数据和版本。REST 无状态,每次请求都要带身份;数据用 JSON 六种类型就够;接口会变,必须先想好版本怎么叠。
一、安全机制的设计
大部分 App 接口走 RESTful。最重要的原则是请求之间无状态:涉及用户状态时,每次都要带身份验证。常见是 token:
-
密码登录成功后,服务器返回 token。 -
客户端把 token 存在本地,后续请求带回去。 -
服务器验 token:错误则重新登录;过期则再发起一次认证拿新 token。
登录接口被劫持时,黑客同时拿到密码和 token,用户只能改密才能夺回控制权。
第一种优化是 HTTPS:HTTP 上加 SSL,压缩加密,能在一定程度上防监听、劫持、重放。SSL 也不是绝对安全;服务器配置复杂,还要向 CA 申请证书(通常收费),效率也较低。安全要求高的系统(如银行)才上 HTTPS,多数 App 仍用 HTTP。
我们目前的做法是给每个接口加签名:给客户端一个密钥,每次把密钥和所有参数拼成源串,按签名算法生成签名,请求一起带上。类似 OAuth1.0。黑客不知道密钥和算法,就算拦到登录接口,后续请求也过不去。签名麻烦、易错,只适合对内接口;开放 API 更建议 OAuth2.0。
再给每个端分配 appKey(Android、iOS、微信各一对 appKey+密钥)。没传或传错 appKey 直接报错。安全多一层,也方便按端做策略。
越来越多 App 取消密码登录,改用手机号+短信验证码:不用注册/改密/重置;用户不用记密码,也不怕泄露;相对密码登录更安全。
二、接口数据的设计
数据用 JSON。值只有六种类型:Number、String、Boolean、Array、Object、Null。不要传超出这六种的东西。曾经传过 Date,会变成类似 2016年1月7日 09时17分42秒 GMT+08:00 的字符串,不同解析库表现不同,有的直接异常。日期用毫秒数最干净。
还出现过字符串的 "true" / "false"、字符串数字,甚至字符串 "null",后者直接让 App 崩溃。服务端没处理好会把数据转成字符串;客户端也不能完全信任服务端,异常都要兜住。
服务器返回结构一般为:
-
code:0 成功,非 0 各种错误 -
message:成功为 success,失败为错误信息 -
data:成功时的数据,对象或数组
不同错误定义不同返回码,客户端错误和服务端错误要分开,例如 1XX 客户端、2XX 服务端:
-
0:成功 -
100:请求错误 -
101:缺少 appKey -
102:缺少签名 -
103:缺少参数 -
200:服务器出错 -
201:服务不可用 -
202:服务器正在重启
错误信息一是给客户端开发调试,二是直接展示给用户。主要还是给用户看,所以要短。data 只在成功时有,类型限定对象或数组。不要把 data 传成裸字符串或数字,即便只要一个 token:
三、接口版本的设计
接口会变:数据类型变了、参数新增、接口废弃。一般两种做法:
-
每个接口自己的版本,加 version 参数。 -
整套接口统一版本,URL 里加版本号,比如 http://api.domain.com/v2。
多数用第一种:某个接口变了就叠加版本并兼容旧版,App 新版本传新 version。整套根基都变(例如微博 API 从 OAuth1.0 到 OAuth2.0)才走第二种。
一个接口的变动可能影响别的接口,当时不一定能发现。最好有一套测试机制,保证每次变更都能测到相关层面。
| 层面 | 建议 | 别做 |
|---|---|---|
| 安全 | token + 签名 + appKey;对内签名,开放走 OAuth2.0 | 只靠登录接口发 token |
| 数据 | JSON 六种类型;日期用毫秒;code/message/data | Date、字符串 “null”、裸 data |
| 版本 | 单接口 version,兼容旧版 | 改接口不测连带影响 |
一句话总结:身份用 token 还要签名和 appKey;JSON 只走六种类型、data 永远是对象或数组;接口一变就叠加 version 并兼容旧客户端。
转载请注明来源:接口的设计






