答面试官问:如何设计API接口

关于接口设计,需要注意区分pc,wap,app不同端的接口请求和通用性,以及实现签名鉴权,访问控制等功能。

接口参数定义

接口设计中往可以抽象出一些新的公共参数,从事了近三年的接口开发工作中,我目前能想到了一些较为常见的公共接口参数如下:

公共参数 含意 定义该参数的意义
timestamp 毫秒级时间戳 1.客户端的请求时间标示 2.后端可以做请求过期验证 3.该参数参与签名算法增加签名的唯一性
app_key/source 签名公钥(来源) 签名算法的公钥,后端通过公钥可以得到对应的私钥(也就是来源的意义)
sign 接口签名 通过请求的参数和定义好的签名算法生成接口签名,作用防止中间人篡改请求参数
did 设备 ID 设备的唯一标示,生成规则例如android的mac地址的md5和ios曾今udid(目前无法获取)的md5, 1:数据收集 2.便于问题追踪 3.消息推送标示

接口版本化

我不太习惯把版本号直接放到路由里面去,还有其他方式可以区别版本,比如get、post传参。

接口安全性

过期验证

通过时间戳进行验证

if (microtime(true)*1000 - $_REQUEST['timestamp'] > 5000) {

throw new \Exception(401, 'Expired request');

}

签名验证(公钥校验省略,如果是saas,密钥可能不同)

通过配对私钥的加密算法产生签名,请求中携带签名进行鉴权。

$params = ksort($_REQUEST);

unset($params['sign']);

$sign = md5(sha1(implode('-', $params) . $_REQUEST['app_key']));

if ($sign !== $_REQUEST['sign']) {

throw new \Exception(401, 'Invalid sign');

}

重放攻击

防止一次相同请求多次攻击API服务器。

/**

@params noise string 随机字符串或随机正整数,与 Timestamp 联合起来, 用于防止重放攻击 例如腾讯云是6位随机正整数

*/

$key = md5("{$_REQUEST['REQUEST_URI']}-{$_REQUEST['timestamp']}-{$_REQUEST['noise']}-{$_REQUEST['did']}");

if ($redisInstance->exists($key)) {

throw new \Exception(401, 'Repeated request');

}

限流

防止同一ip频繁访问API服务器。

$key = md5("{$_REQUEST['REQUEST_URI']}-{$_REQUEST['REMOTE_ADDR']}-{$_REQUEST['did']}");

if ($redisInstance->get($key) > 60) {

throw new \Exception(401, 'Request limit');

}

$redisInstance->incre($key);

转义

防止注入,xss等攻击。

$username = htmlspecialchars($_REQUEST['username']);

接口的解耦设计

  1. 活用中间件、钩子

  2. 借口多用post请求,少用get

  3. 废弃的代码及时删掉,或者注释掉并且标注

  4. 接口文件合理切割(laravel,lumen等有接口文件的框架)

  5. 服务间调用不要私钥公钥相同,免得一破百破

接口的状态码

推荐一些公用的,如果还有私信,广播,商城等状态码可以另加。

200 -> 正常

400 -> 缺少公共必传参数或者业务必传参数

401 -> 接口校验失败 例如签名

403 -> 没有该接口的访问权限

499 -> 上游服务响应时间超过接口设置的超时时间

500 -> 代码错误

501 -> 不支持的接口method

502 -> 上游服务返回的数据格式不正确

503 -> 上游服务超时

504 -> 上游服务不可用

引用自我的电子书

PHPer面试-2020

本作品采用《CC 协议》,转载必须注明作者和本文链接
是非之外有一座花园,我们会在那里相遇
本帖由系统于 2周前 自动加精
Martist
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 5

file 这个Markdown表格的样式都乱了。。

1个月前 评论

这些好像laravel的路由都帮忙做好了吧

1个月前 评论
Martist

@bibace 甚至做的更全

3周前 评论

大佬求解释

file

2周前 评论
坐忘 2周前
嘿喵财运旺旺 (作者) 1周前

用POST少用GET?这不是在误导别人?

2周前 评论
l333308 3天前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!