认证
合作方密钥、二十六个权限范围、一份授权意味着什么,以及如何在不停机的情况下轮换。
每一个合作方 API 请求都携带一份凭据,放在标准的位置:
Authorization: Bearer brp_<prefix>.<secret>
没有别的方案。没有放在查询字符串里的密钥,没有 basic auth,没有 cookie。缺少这个
请求头、或者值格式不对的请求,会在其他一切被判断之前就返回 401。
密钥是什么
一把密钥由一个点分成两半。
| 半段 | 是什么 | 可以出现在哪里 |
|---|---|---|
brp_<prefix> | 这份凭据的公开标识符。 | 你的日志、一封支持邮件、本站上的密钥列表。 |
<secret> | 256 位随机数。 | 你的密钥管理器,以及 Authorization 请求头。 |
BackResto 保存前缀和密钥串的带密钥摘要。密钥串本身不会被保存,也无法找回—— 你找不回,支持人员找不回,从数据库里也找不回。如果它丢了,吊销这把密钥,再造 一把。
授权:餐厅 × 权限范围
一把密钥不是「一个带权限的账号」。它是一份明确授权的清单,每一条都是一个组合:
一共有二十六个权限范围,它们的构词法值得一次性搞清楚:
| 权限范围 | 授予对什么的访问 |
|---|---|
deliveries:read | 收货记录列表和收货记录详情两个端点。 |
delivery-images:read | 附在一条收货记录上的照片。 |
<collection>:read | 那二十四个集合中的一个——cooling:read、temperature-records:read、traceability-labels:read 等等,一个集合一个权限范围。 |
每一个权限范围都以 :read 结尾。没有任何一个合作方权限范围可以写入,也造不出这样
的权限范围:这个 API 的写入一侧属于 BackResto 应用,而一把合作方密钥在结构上就不
可能持有写入权限。
一把在 restaurant-1 和 restaurant-2 上被授予 deliveries:read、却只在
restaurant-1 上被授予 delivery-images:read 的密钥,能读到第一家餐厅的照片,
对第二家则得到 403。这是一种受支持的配置,不是配错了——有些集成要的就是记录
而不要图片。
只申请你用得上的。二十六个权限范围不是一份用来逐项打钩的菜单:餐厅会在同意之前读 一遍这份清单,而一份「全都要」的申请,比一份只要你的产品真正会读的那四个集合的 申请,走完流程要久得多。
三种失败模式,有意区分开:
404——密钥对那家餐厅根本没有任何授权。API 不会向一个无权的调用方透露某家 餐厅是否存在。403——密钥对那家餐厅有授权,但没有这个端点需要的权限范围。401——除别的情形之外,也包括一把一份授权都不剩的密钥。一把被剥掉最后一份 授权的密钥会停止通过认证,而不是返回空结果。
想知道一把密钥究竟持有什么,就去问它:GET /v1/restaurants 列出那些餐厅及其权限
范围,而
GET /v1/restaurants/{id}/collections 列出它打开的那些集合。
谁可以签发
我们签发,按申请签发,并且只为已经同意的餐厅签发。要发些什么、会拿到什么,见 获取密钥。
授权在密钥开通时确定,只有通过另一次申请才会更改。没有任何一条路径——无论是给你 的还是给我们的——能在餐厅没有再次同意的情况下扩大一把密钥。
过期与吊销
除非你申请的本来就是会过期的密钥,否则密钥不会自行过期。它在被吊销之前一直有效。
吊销立即生效:下一个带着这把密钥的请求返回 401,和一把未知或已过期的密钥得到的
答复相同。它无法撤销,也不需要撤销——替代品是一把新密钥,而不是一把被恢复的旧
密钥。
不停机轮换
一个集成可以同时持有两把有效密钥,所以轮换不需要维护窗口。请我们做轮换,顺序是 这样的:
- 我们签发第二把密钥,餐厅和权限范围与原来相同。
- 你部署新的密钥串,并在它到处都生效之后告诉我们。
- 我们确认旧密钥已经不再被使用——我们能看到每把密钥最后一次通过认证是什么时候, 正是这个信号让第 4 步是安全的。
- 我们吊销旧的那把。
按你自己选的节奏轮换,并在你希望旧密钥消失之前提前几天提出申请:第 2 步和第 3 步 需要你我配合,而上面这个顺序的全部意义,就是任何时候都不会有一段短暂的中断。
操作守则
- 到手就存好,然后删掉那封邮件。 做完这件事之后,密钥串正好只存在于两个地方:
你的密钥管理器,以及
Authorization请求头。 - 一个部署一把密钥,而不是一家公司一把。一把泄露的预发布密钥不该变成一次生产 事故,一次吊销也不该拖垮泄露的那个东西之外的任何东西。
- 绝不要把密钥串发给我们——不要写进工单,也不要拿它来指认一把密钥。公开前缀就 能毫不含糊地指明它,而且写在哪里都安全。
- 在你自己的监控里盯住
401。 一把开始失败的密钥是被吊销了,答案是一场对话, 而不是一个重试循环。