我有一个仅在Rails中构建的API应用程序,它需要加密登录才能接收令牌。随后,来自API的数据请求将使用请求标头中的标记值进行身份验证。
我有另一个Rails应用程序,它使用这个API来做一些不同的事情。目前我已将其设置为在发出任何请求之前进行身份验证,该请求获取该请求的令牌。
这很好,除非它在公众可以获得申请后设置了潜在的竞争条件。两个请求可能几乎同时进入,重置令牌两次,使后续的数据请求之一成为不再有效的令牌。
我想使用$ global变量来存储令牌及其刷新的日期/时间,以便它始终可供所有用户使用,并且仅在令牌超过几个小时时才刷新令牌。
这将解决竞争条件问题,但是从我正在阅读的所有内容中使用轨道中的全局变量是很糟糕的。在我看来,这个用例是一个例外,但我想以正确的方式做到这一点。
我唯一的选择是将这些值存储在我自己的数据库中吗?为一个只包含两列和两行的表设置数据模型似乎很愚蠢,但我不知道这是Rails Way(TM)还是Best Way。
任何建议表示赞赏。
你可以使用Rails' cache来做到这一点。它存储在内存中,或存储在易失性数据库(如Redis)中。你可以有类似的东西:
def a_cool_token
Rails.cache.fetch("a_cool_token", expires_in: 2.hours.to_i) do
a_method_to_regenerate_a_cool_token
end
end
会发生什么是:
a_cool_token
将其传递给请求时,它将尝试从缓存中获取它;a_method_to_regenerate_a_cool_token
;expires_in
上设置的时间通过时,密钥变为无效。您总是可以使用更多有状态的缓存键,使用一些数据库查询来构建它,如:
Rails.cache.fetch("a_cool_token/#{some_timestamp_that_gets_updated_with_a_cool_token}", expires_in: 2.hours.to_i)
实现def some_timestamp_that_gets_updated_with_a_cool_token
可以在令牌上次更新时检索,如果其他内容在a_cool_token
之外更改令牌,则可以避免过时响应
我希望这有助于为您指出一个“好”的解决方案。