我在Rails中构建了一个仅API的应用程序,该应用程序需要加密的登录名才能接收令牌。随后,使用请求标题中的令牌值对来自API的数据请求进行身份验证。
我还有另一个Rails应用程序,该应用程序将此API用于一些其他事情。目前,我已将其设置为在发出任何请求之前进行身份验证,该请求将获得该请求的令牌。
这很好,除了一旦公众可以使用该应用程序就可以设置潜在的比赛条件。可能实际上有两个请求可能同时出现,两次重置令牌,使随后的一个数据请求成为一个不再有效的令牌。
我想使用$ global变量存储令牌和刷新令牌的日期/时间,以便始终对所有用户可用,并且仅在令牌使用了几个小时以上时才刷新令牌。
这可以解决比赛条件问题,但是从我读到的所有内容来看,在铁路中使用全球变量都是很糟糕的。在我看来,这种用例是个例外,但我想以正确的方式来做。
将这些值存储在我自己的数据库中是我唯一的选择吗?为只包含两列和两行的表建立数据模型似乎很愚蠢,但是我不知道这是Rails Way(TM)还是Best Way。
任何建议都值得赞赏。
答案 0 :(得分:3)
您可以使用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
之外的令牌,可以避免过时的响应
我希望这有助于您找到一个“好的”解决方案。