因为 Ruby 2.6 合并了 RubyGems 3.0.1(实际上他们不是一拨人在维护,如果再加上 Rubygems.org 这个网站,那就是三拨人…),所以你可以在 RubyGems 3.0+ 版本中使用两步验证功能了。这个两步验证是和 Google Authenticator 兼容的。
参考 RubyGems 的这两篇 Guide:
简单来说,你可以选择仅在登录 RubyGems.org 账号的时候启用两步验证,或者要求在 RubyGems 命令行执行一些操作(比如 push、owner)的时候要求输入额外的 6 位数字码。这样可以提高你账号的安全性。
因为每次执行 gem push
的时候,RubyGems 会自动调一个 API 来获取最新的 RubyGems 版本,而在国内这个 API 的访问速度可能非常慢。由于两步验证的安全码是 30 秒生成一次,这个过程可能会超时。
可以去给 RubyGems.org 贡献网站的中文翻译!(这是个 Rails 应用)如果你有余力的话,也可以看看 RubyGems 里的一堆 Issue,可能也和你的日常使用息息相关。这两个项目里面就是普通的 Ruby 代码,上手门槛应该比 Ruby Core 小很多。
这个功能实际上是我实现的,作为 GSoC 2018 的一个项目。RubyGems.org 使用的是 Clearance,所以很多基于 devise 的方案就没法用了。(GitLab 用的也是 devise)如果你也想在你的项目中引入两步验证的话,首要的其实是去了解下两步验证的协议(最常见和兼容的就是 TOTP 和 HOTP 两种,前者更常用),用最通俗的话描述原理就是:把密钥和一个一次性的值(对于 TOTP 就是当前的时间,对于 HOTP 就是当前是第几次验证)合在一起做散列然后模 1000000 得到一个 6 位数的值。
当然我们不用自己去实现这些东西,因为有 rotp 这个库。然后你可以在模型中利用这个库写一些验证的方法,用二维码相关的库来在用户启用两步验证时生成供 Authenticator 扫描的二维码等…当然你得起码在 User
模型中引入前面提到的两步验证的密钥,叫 seed 也好 secret 也好。然后很多网站给用户提供了 recovery token,就是当用户手机丢了或者其他没法生成验证码的时候临时使用的若干验证码(一次性的)。如果你用 PG 作为数据库的话,这个字段就可以直接用 Array 了。其他的一些要求可以参考 rotp 的文档。我在想要不要把这些做成一个 gem,但是不够抽象好像也没必要。
最后,希望大家多给 Rails、RubyGems 和 Ruby 提 Issue、修 bug,因为咱们社区的人真的不多。Andre Arko(Bundler 的作者)三天两头说自己看到隔壁 JS 社区挺嫉妒的,因为 NPM 还能开个公司拿风投…
顺便,最近一直强调网络安全,但是国内就没几家的产品兼容两步验证的,就算要实名,手机号这玩意用来保护账号,也不安全啊。