首页 > 后端开发 > Golang > 制作漂亮的 API 密钥

制作漂亮的 API 密钥

Barbara Streisand
发布: 2025-01-11 08:52:41
原创
403 人浏览过

Making Beautiful API Keys

摘要: AgentStation 为了提升开发者体验,创建了 uuidkey 包,将 UUID 编码成美观易读的 API 密钥。该包支持 UUIDv7,并可解码密钥以便数据库排序和索引。

问题:

API 密钥是用户与 AgentStation 产品初次交互的重要环节。我们希望密钥既美观又易用,但行业中似乎缺乏统一标准。作为一家以开发者为中心的初创公司,我们投入时间和精力寻找理想的解决方案。

大多数 API 密钥都很糟糕:

我们对 API 密钥提出了以下要求:

  • 安全
  • 全局唯一
  • 可排序
  • 在 Postgres 中性能优异
  • 外观美观

然而,大多数 API 密钥都缺乏美感,通常是格式不一致的随机字符,难以阅读、排序和识别。 我们希望 API 密钥也具备美感,如同生活中美好的事物一样对称。

我们拒绝的 ID:

过于随机、容易猜测、外观难看……都不尽如人意。

  • 整数和 BigInt: 简单易读,易于排序。但它们会暴露密钥数量,且容易猜测,安全性不足。
  • NanoIDs: 提供完全随机、可自定义的 ID,特别适合面向公众的标识符。但缺乏用于排序和调试的时间戳信息。
  • UUIDs: 行业标准,有两个版本值得考虑:
    • UUIDv4:纯随机字符,简单有效。
    • UUIDv7:包含时间戳,便于调试和数据库查询排序。
  • ULIDs: 包含时间戳并使用 Base32 编码,提高可读性。但我们更倾向于 UUID 原生的 Postgres 支持,且其美观性仍不足。

我们的解决方案:

由于现有方案的美观性(对称性)不足,我们创建了自己的方法:

  1. 使用 UUIDv7 作为基础 ID,利用时间戳信息。
  2. 使用 Crockford Base32 编码提高可读性。
  3. 添加美观的破折号以增强视觉效果。

结果:

<code>key, _ := uuidkey.Encode("d1756360-5da0-40df-9926-a76abff5601d")
fmt.Println(key) // Output: 38QARV0-1ET0G6Z-2CJD9VA-2ZZAR0X</code>
登录后复制
登录后复制

我们的密钥:

  • 31 个字符(不含破折号为 28 个),比 UUID 的 36 个字符更短。
  • 高度可读的段落,包含 4 组 7 个大写字母和数字,具有“块状”的美感和可读性。
  • 以解码后的 UUID 形式存储时,可以按时间顺序排序。
  • 用户可见的密钥中时间戳被模糊处理(但精通技术的使用者仍然可以解码)。我们认为密钥中的时间戳元数据是一个额外的好处,您也可以选择使用 UUIDv4!

为什么选择 UUIDv7?

除了时间戳的优势外,UUIDv7 将在 Postgres v18 中获得原生支持。虽然目前可以使用扩展在服务器端生成 UUIDv7,但原生 Postgres 支持的性能肯定会更好,并且可以很好地与 uuidkey.Encode() 配合使用。

在我们的实现中,我们目前在应用程序层生成密钥,并将其作为 UUID 存储以进行排序和索引。一旦发布 Postgres v18,我们将切换到 Postgres 生成,以减轻应用程序层的负载并获得更好的性能。

为什么选择 Crockford Base32?

我们选择 Crockford Base32 编码是因为它:

  • 只使用大写字母和数字,提高了可读性。
  • 将密钥长度减少约 1/5。
  • 映射高效且可预测。

为什么使用破折号?

带破折号的密钥“块状”且对称。如果将各个字符灰显,它们看起来几乎像条形码。我们认为这使得快速读取密钥的一部分以识别它变得容易。

破折号确实会移除方便的双击复制功能,但我们认为这是为了可读性而值得的权衡。我们不希望用户到处复制粘贴它们,事实上我们希望它们得到谨慎处理。理想情况下,用户只在我们的仪表盘中生成密钥时复制一次密钥——因此我们在 UI 中添加了一个复制按钮来解决这个问题。

uuidkey 包:

我们在 github.com/agentstation/uuidkey 上开源了这些设计选择。如果您认同我们的美学、推理和对称性,并希望拥有自己美观的 API 密钥,欢迎试用我们的开源项目。

uuidkey 包的核心是通过 Base32-Crockford 编解码器将 UUID 编码为可读的密钥格式,并将其解码回 UUID。

编码:

代码片段已在原文中给出,此处不再赘述。

解码:

代码片段已在原文中给出,此处不再赘述。

该包旨在与遵循官方 UUID 规范 (RFC 4122) 的任何 UUID 配合使用,但我们专门测试并维护与两个最流行的 UUID Go 生成器的兼容性:

  • Gofrs
  • Google

安装很简单:

<code>key, _ := uuidkey.Encode("d1756360-5da0-40df-9926-a76abff5601d")
fmt.Println(key) // Output: 38QARV0-1ET0G6Z-2CJD9VA-2ZZAR0X</code>
登录后复制
登录后复制

基本用法:

<code>go get github.com/agentstation/uuidkey</code>
登录后复制

我们努力将开销降至最低:

性能基准测试数据已在原文中给出,此处不再赘述。

贡献给 uuidkey:

我们致力于维护 uuidkey 作为可靠的开源工具,因为我们在生产中使用它——欢迎贡献!

如果您觉得它有用或有改进建议,我们很乐意在我们的 GitHub issues 或 Discord 社区中听到您的意见。

先前技术和巨人肩膀:

在我们发布项目后,我们发现了一些具有类似实现的项目,但仍然没有满足我们使用 Go 编码和解码 UUID 的标准。

  • uuidapikey - Go,但不支持编码或解码 UUID 输入。
  • based_uuid - Ruby,但用于公共 ID。

总结:

在 AgentStation,我们正在构建一个平台,让 AI 代理拥有自己的虚拟工作站来运行浏览器、参加会议和执行代码。随着我们扩展到数千个工作站,拥有可排序、高性能的密钥是实用的基础设施。

但我们也相信,开发者像我们一样欣赏对称的美好事物,即使是 API 密钥。

我们希望您发现 uuidkey 既实用又美观。

脚注已在原文中给出,此处不再赘述。

以上是制作漂亮的 API 密钥的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板