繁体   English   中英

如何将包含嵌套 json 作为属性字符串的 JSON.parse() json?

[英]How to JSON.parse() json that contains nested json as a string on a property?

我正在尝试解析来自aws secretsmanager的响应

输出如下所示:

{
  "ARN": "arn:aws:secretsmanager:us-west-2:0000:secret:token-0000",
  "Name": "token",
  "VersionId": "0000-0000-0000-0000-0000",
  "SecretString": "{\"TOKEN\":\"000000000000\"}",
  "VersionStages": ["AWSCURRENT"],
  "CreatedDate": "0000"
}

尝试使用JSON.parse()解析此字符串时,它会尝试解析SecretString中已转义引号的字符串值。

我原以为需要分两步JSON.parse响应,但这不起作用。

#!/bin/bash

TOKEN=$(node -e "\
  const result = JSON.parse('$(aws secretsmanager get-secret-value --secret-id $ARN)'); \
  const token = JSON.parse(result.SecretString); \
  console.log(token); \
")

echo $TOKEN

如何防止JSON.parse函数尝试解析SecretString的字符串值 - 或者,是否有更好的方法来获取该值?

JSON.parse不会尝试解析包含在已解析对象中的 JSON 编码字符串,因此我认为这不是导致您的问题的原因。 这更有可能与 shell 对引号的处理有关。

我认为更好的方法是让您的 Node 脚本使用child_process.execFile调用aws CLI,而不是让 shell 调用aws并将结果传递给 Node。

如果您需要从 Node 访问ARN变量,您可以使用process.env.ARN来完成。

这是一些应该可以解决问题的代码:

async function main()
{
    const child_process = require('child_process');
    const util = require('util');
    const execFile = util.promisify(child_process.execFile);
    const json = (await execFile('aws', ['secretsmanager', 'get-secret-value', '--secret-id', process.env.ARN])).stdout;
    const result = JSON.parse(json);
    const token = result.SecretString;
    console.log(token);
}

main();

如果您需要做更多此类事情,可能值得查看适用于 NodeJS 的 AWS 开发工具包 即使使用execFile ,以这种方式以编程方式使用 CLI 工具仍然存在一些缺陷,尤其是当您需要将 JSON 传递CLI 工具时。

你可以做:

 const json = { "ARN": "arn:aws:secretsmanager:us-west-2:0000:secret:token-0000", "Name": "token", "VersionId": "0000-0000-0000-0000-0000", "SecretString": "{\"TOKEN\":\"000000000000\"}", "VersionStages": ["AWSCURRENT"], "CreatedDate": "0000" } json.SecretString = JSON.parse(json.SecretString) const { SecretString: { TOKEN: token } } = json console.log('Token:', token)

尝试使用单引号而不是双引号作为 JSON 的字符串值

 {
  "ARN": 'arn:aws:secretsmanager:us-west-2:0000:secret:token-0000',
  "Name": 'token',
  "VersionId": '0000-0000-0000-0000-0000',
  "SecretString": '{\"TOKEN\":\"000000000000\"}',
  "VersionStages": ['AWSCURRENT'],
  "CreatedDate": '0000'
}

JavaScript 代码是正确的,问题是由 shell 脚本引入的。 您使用命令替换( $(...) ) 来生成 JavaScript 代码。 命令的输出包含"\ ,shell 将它们解释为引号和转义字符,它们不会到达 JavaScript 代码处理的最终字符串。

避免此问题的最简单方法是将aws的输出重定向到文件,然后使用 JavaScript 读取文件的 JSON:

aws secretsmanager get-secret-value --secret-id $ARN) > /tmp/1.json
node -e "
  const result = require('/tmp/1.json');
  const secret = JSON.parse(result.SecretString);
  console.log(secret.TOKEN);
"

或者,比这更容易,安装jq并在一个命令中运行所有内容:

aws secretsmanager get-secret-value --secret-id $ARN) |
  jq -r '.SecretString | fromjson | .TOKEN'

您的 JSON 格式错误,应该是:

const json = {
  "ARN": "arn:aws:secretsmanager:us-west-2:0000:secret:token-0000",
  "Name": "token",
  "VersionId": "0000-0000-0000-0000-0000",
  "SecretString": {"TOKEN":"000000000000"},
  "VersionStages": ["AWSCURRENT"],
  "CreatedDate": "0000"
}

修复后,您可以像这样访问TOKEN

const parsed = JSON.parse(json);
concole.log(parsed.SecretString.TOKEN); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM