AWS Step Functions 和 API Gateway 无法传递 x-api-key 等 http 标头

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

我遇到了一个表面上看起来非常可以解决的问题,但内部确实是一个痛苦的世界。我有一个简单的设置,使用 REST API 调用 AWS 中的步骤函数。我需要将主体和一个标头 x-api-key 作为输入参数传递到步骤函数中的状态机。

问题之一是步骤函数使用

StartExecution
进行积分。这不接受标头。 请参阅此处了解更多信息。因此,必须将标头作为输入主体的一部分传递给状态机。

这里有一些方法,应该有效,或者至少可以有效,但不行。

首先,我尝试了这样的映射功能:

{
  "stateMachineArn": "arn:aws:states:us-east-1:XXX:stateMachine:XXX",
  "headers": {
    "apiKey": "$input.params('x-api-key')"
  },
  "input": "$util.escapeJavaScript($input.json('$')).replaceAll("\\'","'")"
}

或者这个:

{
  "stateMachineArn": "arn:aws:states:us-east-1:XXX:stateMachine:XXX",
  "input": "$util.escapeJavaScript($input.json('$')).replaceAll("\\'","'")",
  "apiKey": "$input.params('x-api-key')"
}

两者都正确获取调用的 x-api-key 和正文(在 API Gateway 日志中确认),并正确转换它们。但是,如上所述,由于 x-api-key 不在输入字符串中,因此在 Step Function 的日志中,它只能看到输入字符串。明确地说,它不仅映射输入字符串,它实际上只接收输入字符串,甚至不接收标头来正确映射它。

这导致了这个潜在的解决方案:

#set($body = $input.json('$'))
#set($token = $input.params().header.get('x-api-token'))

{
    "input":"{\"token\":\"$util.escapeJavaScript($token).replaceAll("\\\\'","'")\",\"body\":$util.escapeJavaScript($body).replaceAll("\\\\'", "'")}",
  "stateMachineArn": "arn:aws:states:us-east-1:XXX:stateMachine:XXX"
}

此映射模板正确地将标头作为输入字符串的一部分传递。但是,在 API Gateway 中,它会导致

"__type": "com.amazon.coral.service#SerializationException"
错误。我尝试过此映射模板的许多变体。大概有接近两打。这包括尝试以不同方式传递和定义输入字符串等变体。使用
util.toJson
进行编码并避免
#set
,如下所示:

{
  "stateMachineArn": "arn:aws:states:us-east-1:XXX:stateMachine:XXX",
  "input": "$util.toJson({
    \"apiKey\": \"$input.params('x-api-key')\",
    \"body\": $input.json('$')
  })"
}

或者这个:

#set($apiKey = $input.params('x-api-key'))
#set($body = $input.json('$'))

#set($inputMap = {
  "apiKey": $apiKey,
  "body": $body
})

{
  "stateMachineArn": "arn:aws:states:us-east-1:XXX:stateMachine:XXX",
  "input": "$util.toJson($inputMap)"
}

显然我错过了一些东西。或者这里有一种不存在的能力。

json amazon-web-services http-headers aws-api-gateway aws-step-functions
1个回答
0
投票

我认为您可能已经了解了此映射,但看起来您缺少 json 中 body 元素值周围的引号:

#set($body = $input.json('$'))

#set($token = $input.params().header.get('x-api-token'))

{ "input":"{"token":"$util.escapeJavaScript($token).replaceAll("\'","'")","body":$util.escapeJavaScript($body).replaceAll("\ '", "'")}", "stateMachineArn": "arn:aws:状态:us-east-1:XXX:stateMachine:XXX" }

应该是:

#set($body = $input.json('$'))

#set($token = $input.params().header.get('x-api-token'))

{ "input":"{"token":"$util.escapeJavaScript($token).replaceAll("\'","'")","body":"$util.escapeJavaScript($body).replaceAll(" \'", "'")"}", "stateMachineArn": "arn:aws:状态:us-east-1:XXX:stateMachine:XXX" }

错误会产生您报告的 SerializationException

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