用于认证令牌的 OCaml GADTs

这篇文章介绍了广义代数数据类型(GADTs)在解析带有模式的复杂对象(如 JWT 认证令牌)中的实际应用,以确保处理复杂令牌模式时的类型安全性和健壮性,使库更可靠且不易出错。

认证令牌(Authentication tokens)

  • 有多种不同类型的认证令牌格式,如 JWT 和 SAML 等,JWT 虽被广泛使用但存在潜在误用风险,不建议通过 JWT 发送私有数据,但在微服务架构中内部使用较有效。
  • JWT 是一种开放的行业标准 RFC 7519 方法,用于在双方之间安全地表示声明,示例编码令牌包含用户信息等多个声明,每个声明称为 JWT 中的“claim”。
  • 现实中 JWT 声明通常遵循某种格式/模式/强类型表示,具有任意复杂性,文中给出了一个简单的 JWT 示例及其对应的 JSON 模式。

如何解码 JWT(Ok, so how to decode JWT)

  • 首先创建用于解码令牌的类型,如jwt_token包含headerdata_encodingdata等字段,为使jwt_token更结构化,添加类型来表示声明,如jwt_claimjwt_data等。
  • 客户端可通过retrieve_claim函数根据键获取声明并解码,但当不同模式的数量增长时,创建大量样板声明提取函数会很繁琐且易出错,如复制粘贴代码可能导致错误。

GADTs 攻击 JWT 解码(GADTs attack JWT decoding)

  • API 的主要功能是从 JWT 令牌中检索数据,客户端希望只获取所需数据,如本地化模块不需要知道用户年龄。
  • 引入Result.t来传递详细错误,'a claim_typ是 GADT 表示特定的声明类型,通过retrieve_claim函数可实现对任意声明类型的通用检索。
  • 对比 GADT 和非 GADT 在添加新声明和检索声明方面的差异,GADT 使 API 更具扩展性、类型安全性且不易出错,添加新声明时必须添加新构造函数并处理,否则代码无法编译。

结论(Conclusion)

  • GADT 基 API 更小,更易于理解和维护,客户端只需使用两个函数。
  • 是类型安全且不易出错的,添加新声明类型时代码会在编译时出错,而非 GADT 解决方案则无此保证,容易出现拼写错误。
  • 强制处理新声明,支持新声明时必须添加新构造函数并返回预期类型,否则代码无法编译。

关于 GADTs 的更多内容(More about GADTs)

推荐阅读 Raphael Proust、Mads Hartmann 和 Leandro Ostera 等人关于 GADTs 的文章以了解更多。

订阅(Subscribe)

喜欢这篇文章可关注作者的社交媒体和 GitHub 账号。

阅读 6
0 条评论