所有文章 > API设计 > 如何在记录 3scale API 网关的 API 调用时获取客户和应用程序上下文

如何在记录 3scale API 网关的 API 调用时获取客户和应用程序上下文

由于 API 处理大量不同类型的数据,因此对于任何数据提供商来说,关键问题是如何具体地保护这些数据。身份验证方法使开发人员能够构建满足其所有需求的应用程序,确定谁可以访问 API 以保护敏感数据并确保请求不会被篡改。身份验证是实体证明身份的过程。简而言之,身份验证是验证您是否是您所声称的人的行为。如果没有身份验证,就无法轻松地将请求与特定用户数据关联起来,也无法保护请求免受可能删除其他用户数据的恶意用户的攻击。身份验证不应该是事后才想到的,而应该内置到 API 的结构中。

身份验证模式

根据我们的 API,我们可能需要使用不同的身份验证模式来颁发访问 API 的凭据。这些可以是 API 密钥,也可以是自定义配置。

3Scale支持以下身份验证模式:

标准 API 密钥

一种身份验证模型,其中单个随机字符串或哈希充当标识符和秘密令牌。每个具有 API 权限的应用程序都有一个唯一的字符串。默认情况下,密钥参数的名称是user_key。在对 3scale 进行授权调用之前,我们可以使用此相同的标签或选择另一个标签。

应用程序标识符和密钥对

一种身份验证模型,其中不可变标识符 – 应用程序 ID (App_Id) 和可变密钥字符串 – 应用程序密钥 (App_Keys) 分为两个令牌。是App_Id恒定的,可能是也可能不是秘密。每个应用程序可能有 1-n 个应用程序密钥,其中每个密钥都直接相关App_Id,应被视为秘密。

在 3Scale 中,每个服务可以使用不同的身份验证模式,但每个服务只能使用一种模式。在身份验证部分,我们可以选择所需的身份验证模式。

3Scale-身份验证模式.png

应用上下文

3Scale 提供了一个管理 API 端点来获取与每个用户关联的应用程序上下文。应用程序上下文包含与单个用户相关的详细信息,包括他们与 3Scale API 的交互,例如first_traffic_atfirst_daily_traffic_at以及其他个人身份信息数据,例如 – user_iduser_account_idservice_idplan信息和其他详细信息。通过访问这些详细信息,可以轻松地将请求与特定用户关联起来。

根据我们使用的身份验证方法,我们调用管理端点来获取应用程序上下文。使用标准 API 密钥身份验证方法时,我们通过调用此端点来获取应用程序上下文 –

curl -v -X GET "https://#{domain}/admin/api/applications.xml?access_token=#{ADMIN_ACCESS_TOKEN}&user_key=#{user_key}"

在使用应用程序标识符和密钥对身份验证方法时,我们通过调用此端点来获取应用程序上下文 –

curl -v -X GET "https://#{domain}/admin/api/applications.xml?access_token=#{ADMIN_ACCESS_TOKEN}&app_id=#{app_id}&app_key=#{app_key}"

使用 3Scale 设置 Moesif API 分析

Moesif 有一个Luarocks 中可用的插件捕获 API 请求和响应并记录到 Moesif,以便通过 3Scale 轻松检查和实时调试 API 流量。该插件在本地捕获指标并对其进行排队,这使得该插件能够将指标数据发送到 Moesif 收集网络,而不会影响您的应用。

推荐通过 Luarocks 安装 Moesif:

luarocks install --server=http://luarocks.org/manifests/moesif lua-resty-moesif

身份验证凭证位置

3Scale 为最终用户提供了灵活性,使其可以在调用 API 时通过HTTP_Headers或传递身份验证凭据query_parameters。Moesif 会在标头和查询参数中查找凭据并获取该特定用户的应用程序上下文。Moesif 提供了一个配置选项来设置字段名称,该名称与配置 API 身份验证设置时使用的名称相同。默认情况下,3Scale 使用user_key标准 API 密钥和app_idApp_Idapp_key和 App_Key 对身份验证方法。

识别用户和公司(账户)

管理端点将应用程序上下文作为 XML 实体返回。Moesif 提供了一个配置选项,用于设置 3Scale 应用程序 XML 实体中的字段名称,该字段名称将用于识别用户和公司(帐户)。默认情况下,用户和公司的字段名称为iduser_account_id,但其他有效示例包括user_keyservice_id

-- Function to parse 3Scale XML entity
-- @param `user_id_name` The 3scale field name from 3scale's application XML entity used to identify the user. Default `id`.
-- @param `company_id_name` The 3scale field name from 3scale's application XML entity used to identify the company (account). Default `user_account_id`.
-- @param `debug` A flag to print logs
function parseXML(user_id_name, company_id_name, debug)
-- config_response is the response from an api call to fetch application context which is a XML entity
local response_body = config_response:match("(%<.*>)")
if response_body ~= nil then
local xobject = xml.eval(response_body)
local xapplication = xobject:find("application")
if xapplication ~= nil then
local xtable = {}
for k, v in pairs(xapplication) do
if v ~= nil and type(v) == "table" then
xtable[v:tag()] = k
end
end

local key = xapplication[xtable[user_id_name]]
if key ~= nil then
if debug then
ngx.log(ngx.DEBUG, "Successfully fetched the userId ")
end
-- Set the UserId
local user_id = key[1]
else
if debug then
ngx.log(ngx.DEBUG, "The user_id_name provided by the user does not exist ")
end
end
local companyKey = xapplication[xtable[company_id_name]]
if companyKey ~= nil then
if debug then
ngx.log(ngx.DEBUG, "[moesif] Successfully fetched the companyId (accountId) ")
end
-- Set the CompanyId (AccountId)
local company_id = companyKey[1]
else
if debug then
ngx.log(ngx.DEBUG, "[moesif] The company_id_name provided by the user does not exist ")
end
end
else
if debug then
ngx.log(ngx.DEBUG, "Application tag does not exist ")
end
end
else
if debug then
ngx.log(ngx.DEBUG, "Xml response body does not exist ")
end
end
end

结论

通过这种方式,插件会将每个事件或动作链接到单个客户,并且可以通过查看多个事件来发现行为趋势,以识别产品问题,例如用户为什么停止使用您的 API 或他们最常使用哪些功能或端点。

原文地址:https://www.moesif.com/blog/technical/3scale/How-to-Get-Customer-and-Application-Context-When-Logging-API-Calls-for-3scale-API-Gateway/