ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
关于接口设计,需要注意区分**PC**,**WAP**,**APP**不同端的接口请求和通用性,以及实现**签名鉴权**,**访问控制**等功能。 ## **公共参数** 公共参数是每个接口都要携带的参数,描述每个接口的基本信息,用于统计或其他用途,放在 header 或者 url 参数中 * **timestamp** 毫秒级时间戳: 1. 客户端的请求时间标示 2. 后端可以做请求过期验证 3. 该参数参与签名算法增加签名的唯一性 * **app_key/source** 签名公钥(来源): 签名算法的公钥,后端通过公钥可以得到对应的私钥 * **sign** 接口签名: 通过请求的参数和定义好的算法生成接口签名,作用防止`中间人`篡改请求参数 * **did** 设备ID: 设备的唯一标示,生成规则例如 Android 的 MAC 地址的md5和 ios 曾今 udid(目前无法获取)的md5。 1. 数据收集 2. 便于问题追踪 3. 消息推送标示 * version 客户端版本 * token 登录令牌 * os 手机系统版本 * from 请求来源 * screen 手机尺寸 * model 机型 * net 网络状态 ## **响应数据** 响应数据会包含三个属性,**状态码(code**,**信息描述(message**,**响应数据(data)**。 ~~~json { "code": 1, "message": "成功", "data": { "list": [] } } ~~~ ## **接口安全性** ### **过期验证** 通过时间戳进行验证 ~~~php if (microtime(true) * 1000 - $REQUEST['timestamp'] > 5000) { throw new \Exception(401, 'Expired request'); } ~~~ ### **签名验证(公钥效验省略,如果是 saas,密钥可能不同)** 通过配对私钥的加密算法产生签名,请求中携带签名进行鉴权。 ~~~php $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 服务器 ~~~php /** @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 服务器 ~~~php $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 攻击 ~~~php $username = htmlspecialchars($_REQUEST['username']); ~~~ ## **接口的解耦设计** 1. 活用中间件、钩子。 2. 借口多用 POST请求,少用 get 3. 废弃的代码及时删除,或者注释并标注 4. 接口文件合理切割(laravel,lumen等有接口文件的框架) 5. 服务间调用不要私钥公钥相同,免得一破百破 ## **接口的状态码** ~~~ 200 -> 正常 400 -> 缺少公共必传参数或者业务必传参数 401 -> 接口校验失败 例如签名 403 -> 没有该接口的访问权限 499 -> 上游服务响应时间超过接口设置的超时时间 500 -> 代码错误 501 -> 不支持的接口method 502 -> 上游服务返回的数据格式不正确 503 -> 上游服务超时 504 -> 上游服务不可用 ~~~