在App Builder操作中生成JWT访问令牌

App Builder操作可能需要与与App Builder应用程序也部署的Adobe Developer Console项目关联的AdobeAPI进行交互。

这可能要求App Builder操作生成与所需Adobe Developer Console项目关联的自己的JWT访问令牌。

IMPORTANT
查看App Builder安全文档以了解何时生成访问令牌与使用提供的访问令牌相比较合适。
自定义操作可能需要提供自己的安全检查,以确保仅允许的使用者可以访问App Builder操作及其后面的Adobe服务。

.env文件

在App Builder项目的.env文件中,为每个Adobe Developer Console项目的JWT凭据附加自定义密钥。 可以从给定工作区的Adobe Developer Console项目的​ 凭据 > 服务帐户(JWT) ​获取JWT凭据值。

Adobe Developer Console JWT服务凭据

...
JWT_CLIENT_ID=58b23182d80a40fea8b12bc236d71167
JWT_CLIENT_SECRET=p8e-EIRF6kY6EHLBSdw2b-pLUWKodDqJqSz3
JWT_TECHNICAL_ACCOUNT_ID=1F072B8A63C6E0230A495EE1@techacct.adobe.com
JWT_IMS_ORG=7ABB3E6A5A7491460A495D61@AdobeOrg
JWT_METASCOPES=https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk,https://ims-na1.adobelogin.com/s/event_receiver_api
JWT_PRIVATE_KEY=LS0tLS1C..kQgUFJJVkFURSBLRVktLS0tLQ==

可以从Adobe Developer Console项目的JWT凭据屏幕直接复制JWT_CLIENT_IDJWT_CLIENT_SECRETJWT_TECHNICAL_ACCOUNT_IDJWT_IMS_ORG的值。

Metascopes

确定App Builder操作与之交互的AdobeAPI及其元数据。 在JWT_METASCOPES键中列出带有逗号分隔符的metascope。 Adobe的JWT Metascope文档中列出了有效的Metascope。

例如,可以将以下值添加到.env中的JWT_METASCOPES键中:

...
JWT_METASCOPES=https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk,https://ims-na1.adobelogin.com/s/event_receiver_api
...

私钥

JWT_PRIVATE_KEY必须经过特殊格式设置,因为它本身是多行值,在.env文件中不支持该值。 最简单的方法是对私钥进行base64编码。 可以使用操作系统提供的本机工具对私钥(-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----)进行Base64编码。

macOS
  1. 打开Terminal

  2. 运行命令base64 -i /path/to/private.key | pbcopy

  3. base64输出将自动复制到剪贴板中

  4. 将值粘贴到.env中以作为相应键的值

Windows
  1. 打开Command Prompt

  2. 运行命令certutil -encode C:\path\to\private.key C:\path\to\encoded-private.key

  3. 运行命令findstr /v CERTIFICATE C:\path\to\encoded-private.key

  4. 将base64输出复制到剪贴板

  5. 将值粘贴到.env中以作为相应键的值

Linux®
  1. 打开终端

  2. 运行命令base64 private.key

  3. 将base64输出复制到剪贴板

  4. 将值粘贴到.env中以作为相应键的值

例如,可以将以下base64编码私钥添加到.env中的JWT_PRIVATE_KEY密钥:

...
JWT_PRIVATE_KEY=LS0tLS1C..kQgUFJJVkFURSBLRVktLS0tLQ==

输入映射

.env文件中设置JWT凭据值后,必须将它们映射到AppBuilder操作输入,以便在操作本身中读取它们。 为此,请在ext.config.yaml操作inputs中为每个变量添加条目,格式为: PARAMS_INPUT_NAME: $ENV_KEY

例如:

operations:
  view:
    - type: web
      impl: index.html
actions: actions
runtimeManifest:
  packages:
    dx-excshell-1:
      license: Apache-2.0
      actions:
        generic:
          function: actions/generic/index.js
          web: 'yes'
          runtime: nodejs:16
          inputs:
            LOG_LEVEL: debug
            JWT_CLIENT_ID: $JWT_CLIENT_ID
            JWT_TECHNICAL_ACCOUNT_ID: $JWT_TECHNICAL_ACCOUNT_ID
            JWT_IMS_ORG: $JWT_IMS_ORG
            JWT_METASCOPES: $JWT_METASCOPES
            JWT_PRIVATE_KEY: $JWT_PRIVATE_KEY
          annotations:
            require-adobe-auth: false
            final: true

inputs下定义的键在提供给App Builder操作的params对象上可用。

用于访问令牌的JWT凭据

在App Builder操作中,JWT凭据在params对象中可用,可由@adobe/jwt-auth用于生成访问令牌,该令牌反过来可以访问其他AdobeAPI和服务。

const fetch = require("node-fetch");
const { Core } = require("@adobe/aio-sdk");
const { errorResponse, stringParameters, checkMissingRequestInputs } = require("../utils");
const auth = require("@adobe/jwt-auth");

async function main(params) {
  const logger = Core.Logger("main", { level: params.LOG_LEVEL || "info" });

  try {
    // Perform any necessary input error checking
    const systemErrorMessage = checkMissingRequestInputs(params, [
            "JWT_CLIENT_ID", "JWT_TECHNICAL_ACCOUNT_ID", "JWT_IMS_ORG", "JWT_CLIENT_SECRET", "JWT_METASCOPES", "JWT_PRIVATE_KEY"], []);

    // Split the metascopes into an array (they are comma delimited in the .env file)
    const metascopes = params.JWT_METASCOPES?.split(',') || [];

    // Base64 decode the private key value
    const privateKey = Buffer.from(params.JWT_PRIVATE_KEY, 'base64').toString('utf-8');

    // Exchange the JWT credentials for an 24-hour Access Token
    let { accessToken } = await auth({
      clientId: params.JWT_CLIENT_ID,                          // Client Id
      technicalAccountId: params.JWT_TECHNICAL_ACCOUNT_ID,     // Technical Account Id
      orgId: params.JWT_IMS_ORG,                               // Adobe IMS Org Id
      clientSecret: params.JWT_CLIENT_SECRET,                  // Client Secret
      metaScopes: metascopes,                                  // Metadcopes defining level of access the access token should provide
      privateKey: privateKey,                                  // Private Key to sign the JWT
    });

    // The 24-hour IMS Access Token is used to call the Analytics APIs
    // Can look at caching this token for 24 hours to reduce calls
    const accessToken = await getAccessToken(params);

    // Invoke an exmaple Adobe API endpoint using the generated accessToken
    const res = await fetch('https://analytics.adobe.io/api/example/reports', {
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "X-Proxy-Global-Company-Id": 'example',
        "Authorization": `Bearer ${accessToken}`,
        "x-Api-Key": params.JWT_CLIENT_ID,
      },
      method: "POST",
      body: JSON.stringify({... An Analytics query ... }),
    });

    if (!res.ok) { throw new Error("Request to API failed with status code " + res.status);}

    // Analytics API data
    let data = await res.json();

    const response = {
      statusCode: 200,
      body: data,
    };

    return response;
  } catch (error) {
    logger.error(error);
    return errorResponse(500, "server error", logger);
  }
}

exports.main = main;
recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69