将配置和密钥与Edge函数结合使用
了解如何通过edgeFunctions.yaml将非敏感的 配置 和敏感的 密钥 传递给AEM Edge函数,并在代码中读取它们。
配置和密钥
configs和secrets都是您向AEM Edge函数公开的键/值对。
不同之处在于价值存在的地方,以及它的敏感程度。
configssecretsedgeFunctions.yaml,提交到GitedgeFunctions.yaml引用的Cloud Manager密钥config_defaultsecret_defaultConfigStore.get() (同步)SecretStoreManager.getSecret() (异步)edgeFunctions.yaml中仅提交引用${{SECRET_NAME}}configs中放入敏感值。 edgeFunctions.yaml文件已提交到Git,因此其配置值对具有存储库访问权限的任何人都可见。 将secrets用于令牌、密钥和凭据。声明配置和机密的位置
在edgeFunctions.yaml中的data下将两者声明为functions的同级。 它们不会嵌套在单个函数下。
# config/edgeFunctions.yaml
kind: "EdgeFunctions"
version: "1"
data:
functions:
- name: my-edge-function
configs:
- key: TRIPS_API_BASE_URL
value: "https://api.example.com/trips"
- key: ADVENTURE_CACHE_TTL_SECONDS
value: "300"
secrets:
- key: TRIPS_API_TOKEN
value: ${{WKND_TRIPS_API_TOKEN}}
键名称区分大小写。 您在此处声明的key与代码在运行时读取的名称相同。
有关所有支持的属性,请参阅声明函数。
使用配置
配置包含的非敏感值会因环境而异。 配置值始终为字符串,因此,当您需要数字或布尔值时,请强制转换这些值。
读取代码中的配置
打开config_default存储,然后使用您声明的键调用get()。 调用是同步的。
// src/index.js or handler file
import { ConfigStore } from "fastly:config-store";
const config = new ConfigStore("config_default");
// read a config value (always a string)
const apiBaseUrl = config.get("TRIPS_API_BASE_URL");
// cast to a number, with a fallback if the key is missing
const ttlSeconds = Number(config.get("ADVENTURE_CACHE_TTL_SECONDS") || "300");
使用密钥
密钥包含敏感值,例如API令牌。 值将保留在Cloud Manager密码中。 您的edgeFunctions.yaml使用${{SECRET_NAME}}语法引用它,因此该值从不出现在Git中。
涉及两个名字,它们在目的上有所不同。
TRIPS_API_TOKEN (key)edgeFunctions.yaml和您的代码getSecret()的名称WKND_TRIPS_API_TOKEN (在${{ }}内)此示例使用一个密钥和一个密钥,即AEM as a Cloud Service的模式。 在Edge Delivery Services上,每个站点重复一次此模式,因为一个配置管道可为所有三个站点提供服务。
在AEM as a Cloud Service中添加密钥
定义Cloud Manager密钥并运行配置管道,然后再将其用于AEM Edge函数。 每个环境(RDE、Dev、Stage、Prod)都有自己的“配置”选项卡,因此,添加到开发环境的密码在添加到暂存或Prod中之前并不存在。
- 在Cloud Manager中,导航到您的项目 > 环境 > 配置选项卡。
- 选择+添加配置。在 环境配置 模式中,输入名称和值,选择要应用它的服务,并将类型设置为密码。
- 选择+添加,然后选择保存。
在Edge Delivery Services中添加密钥
Edge Delivery Services的每个项目都有一个配置管道,而不是每个站点都有一个配置管道。 它将为整个项目部署单个edgeFunctions.yaml,由每个站点共享,而不是为每个站点部署单独的文件。
开发、暂存和生产站点都共享该管道,因此您不能使用三个不同的值三次添加同一变量名称,也不能依赖特定于分支的edgeFunctions.yaml来选择正确的变量名称。
为每个变量名称添加前缀,以使三个站点绝不冲突,例如DEV_TRIPS_API_TOKEN、STAGE_TRIPS_API_TOKEN和MAIN_TRIPS_API_TOKEN。 在同一个edgeFunctions.yaml中声明所有三个,然后让您的代码在运行时选择正确的一个。
- 在Cloud Manager中,导航到您的项目 > Edge Delivery > 管道分区。选择管道旁边的省略号(
...),然后选择查看/编辑变量。
- 使用站点前缀为每个站点添加一个变量,并将类型设置为密码。
- 在单个
edgeFunctions.yaml中声明所有三个带有前缀的密钥,因为管道会为每个站点部署一次。
# config/edgeFunctions.yaml
secrets:
- key: TRIPS_API_TOKEN_DEV
value: ${{DEV_TRIPS_API_TOKEN}}
- key: TRIPS_API_TOKEN_STAGE
value: ${{STAGE_TRIPS_API_TOKEN}}
- key: TRIPS_API_TOKEN_MAIN
value: ${{MAIN_TRIPS_API_TOKEN}}
AEM Edge函数必须根据它当前提供的网站,决定在运行时读取哪个键。 下一部分将显示查找。
读取代码中的密钥
在运行时通过样板在src/lib/config.js中提供的SecretStoreManager帮助程序读取密码。 它从secret_default存储中读取。 虽然调用在两种平台上都是异步调用,但查找的键值有所不同。
在AEM as a Cloud Service上,密钥是固定的,因为每个环境在相同的密钥名称后面都有自己的密钥:
// src/index.js or handler file
import { SecretStoreManager } from "./lib/config";
const token = await SecretStoreManager.getSecret("TRIPS_API_TOKEN");
if (!token) {
throw new Error("TRIPS_API_TOKEN is not configured");
}
在Edge Delivery Services上,首先从当前站点生成密钥,因为一个共享的edgeFunctions.yaml为每个站点声明了一个单独的密钥:
// src/index.js or handler file
import { SecretStoreManager } from "./lib/config";
const site = getCurrentSite(); // for example, "DEV", "STAGE", or "MAIN" based on the origin header
const token = await SecretStoreManager.getSecret(`TRIPS_API_TOKEN_${site}`);
if (!token) {
throw new Error(`TRIPS_API_TOKEN_${site} is not configured`);
}
获得令牌后,可在两种平台上以相同的方式将其用于出站请求:
// use the token in an outbound request, never in a response to the client
const request = new Request("https://api.example.com/trips", {
headers: { Authorization: `Bearer ${token}` },
});
保守秘密AEM Edge函数。 请勿将其返回给客户端或进行记录。
准则
- 对于任何可安全提交的内容,请使用
configs;对于任何必须保持隐私的内容,请使用secrets。 - 完全匹配键名。 所有键名称都区分大小写。
- 在使用之前转换配置值,因为每个配置值都是字符串。
- 在管道运行或无法解析
${{SECRET_NAME}}引用之前添加Cloud Manager密钥。 - 在Edge Delivery Services上,为每个密码和变量名称添加前缀,并使用其站点(
DEV_、STAGE_、MAIN_)。 一个配置管道可为所有三个站点提供服务,因此非前缀名称会发生冲突,并且您的代码必须在运行时选取正确的前缀。