从我的 Rails 应用程序调用 API 时,我应该将令牌存储在哪里?
Where should I store the token when calling an API from my Rails app?
我正在编写一个库来调用第三方 API,以便 Rails 应用程序可以使用它。为了进行身份验证,API 最初使用基本身份验证 return 用于所有其他请求的令牌。令牌在 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 调用 APIs,我不确定如何处理获得 returned 的令牌。我不想在每次 API 调用之前获取一个新的,因为这似乎不必要地过多,所以我猜将它存储在某个地方是有意义的。
在这种情况下,最好用 token
和 expires_at
列创建一个 acme_tokens
数据库 table,然后在每个新 API打电话?
或者,由于对 API 的调用将由我们 Rails 应用程序前端的用户操作发起,我是否应该将令牌存储在会话变量中?
提前致谢!
因此,我认为您可以使用 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
它将return你的令牌当缓存存在时,如果缓存过期则请求新的令牌。
此外,您需要在 development/production 环境中配置 cache_store。
我想我们将令牌和过期时间保存到数据库模型中。然后我们也可以为此模型使用缓存或不使用缓存(取决于您的应用程序)
我正在编写一个库来调用第三方 API,以便 Rails 应用程序可以使用它。为了进行身份验证,API 最初使用基本身份验证 return 用于所有其他请求的令牌。令牌在 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 调用 APIs,我不确定如何处理获得 returned 的令牌。我不想在每次 API 调用之前获取一个新的,因为这似乎不必要地过多,所以我猜将它存储在某个地方是有意义的。
在这种情况下,最好用 token
和 expires_at
列创建一个 acme_tokens
数据库 table,然后在每个新 API打电话?
或者,由于对 API 的调用将由我们 Rails 应用程序前端的用户操作发起,我是否应该将令牌存储在会话变量中?
提前致谢!
因此,我认为您可以使用 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
它将return你的令牌当缓存存在时,如果缓存过期则请求新的令牌。 此外,您需要在 development/production 环境中配置 cache_store。
我想我们将令牌和过期时间保存到数据库模型中。然后我们也可以为此模型使用缓存或不使用缓存(取决于您的应用程序)