如何为Rails应用程序存储值,该应用程序会定期更改但需要所有用户都可以访问?

问题描述 投票:1回答:1

我有一个仅在Rails中构建的API应用程序,它需要加密登录才能接收令牌。随后,来自API的数据请求将使用请求标头中的标记值进行身份验证。

我有另一个Rails应用程序,它使用这个API来做一些不同的事情。目前我已将其设置为在发出任何请求之前进行身份验证,该请求获取该请求的令牌。

这很好,除非它在公众可以获得申请后设置了潜在的竞争条件。两个请求可能几乎同时进入,重置令牌两次,使后续的数据请求之一成为不再有效的令牌。

我想使用$ global变量来存储令牌及其刷新的日期/时间,以便它始终可供所有用户使用,并且仅在令牌超过几个小时时才刷新令牌。

这将解决竞争条件问题,但是从我正在阅读的所有内容中使用轨道中的全局变量是很糟糕的。在我看来,这个用例是一个例外,但我想以正确的方式做到这一点。

我唯一的选择是将这些值存储在我自己的数据库中吗?为一个只包含两列和两行的表设置数据模型似乎很愚蠢,但我不知道这是Rails Way(TM)还是Best Way。

任何建议表示赞赏。

ruby-on-rails global-variables
1个回答
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

会发生什么是:

  1. 当使用a_cool_token将其传递给请求时,它将尝试从缓存中获取它;
  2. 如果缓存键已过期或未定义,则返回a_method_to_regenerate_a_cool_token;
  3. 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之外更改令牌,则可以避免过时响应

我希望这有助于为您指出一个“好”的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.