从Rails应用程序调用API时,令牌应该存储在哪里?

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

我正在编写一个库来调用第三方API,以便Rails应用可以使用它。为了进行身份验证,API最初使用基本身份验证来返回用于所有其他请求的令牌。令牌在1小时内保持有效,并且可以使用相同的基本身份验证凭据提取多个令牌,而不会使其他令牌无效。

这里是到目前为止的内容的简化版本:

# frozen_string_literal: true

require "rest-client"

class AcmeClient
  ACME_API_URL = Application.secrets.acme[:url]
  ACME_API_KEY = Application.secrets.acme[:key]
  ACME_API_SECRET = Application.secrets.acme[:secret]

  def health_check
    url = ACME_API_URL + "api/health"
    token = fetch_token
    RestClient.get url, { Authorization: "Bearer #{token}"}
  end

  private

  def fetch_token
    url = ACME_API_URL + "/api/token"
    response = RestClient::Request.execute(
      method: :post,
      url: url,
      user: ACME_API_KEY,
      password: ACME_API_SECRET,
      payload: "grant_type=client_credentials"
    )
    JSON.parse(response.body)["access_token"]
  end
end

我已经提供了health_check方法作为可用的API端点的示例。

以前只使用现有的gem来调用API,所以我不确定该如何处理返回的令牌。我不想在每次API调用前都获取一个新的,因为这似乎不必要,所以我想将它存储在某个地方是很有意义的。

在这种情况下,最好创建具有​​acme_tokenstoken列的expires_at数据库表,然后在每次新的API调用之前检查到期时间吗?

或者,由于API的调用将由我们Rails应用程序前端中的用户操作来发起,因此我应该将令牌存储在会话变量中吗?

提前感谢!

ruby-on-rails ruby rest-client
1个回答
2
投票

所以,我认为您可以使用rails low-level cache 来存储令牌。如下修改您的fetch_token方法:

  def fetch_token
    Rails.cache.fetch("#{cache_key_with_version}/my_api_token", expires_in: 1.hour) do
      url = ACME_API_URL + "/api/token"
      response = RestClient::Request.execute(
        method: :post,
        url: url,
        user: ACME_API_KEY,
        password: ACME_API_SECRET,
        payload: "grant_type=client_credentials"
      )
      JSON.parse(response.body)["access_token"]
    end
  end

它将在缓存处于活动状态时返回您的令牌,如果缓存已过期,则请求新的令牌。另外,您需要在开发/生产环境中配置您的cache_store。

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