使用cURL在JSON中发布请求失败

x0fgdtte  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(298)

我正在努力使用cURL生成一个正确的JSON POST请求。为此,我编写了一个简短的shell脚本,但很明显,我的JSON字符串似乎有问题(根据下面列出的错误消息)。
如果我将CSR直接写入JSON字符串,它将工作得很好:

authToken="Here'sMyAuthToken"
curl --data-binary '{"authToken" : "'$authToken'", "order" : {"type" : "DomainValidatedCertificateOrder", "csr" : "-----BEGIN CERTIFICATE REQUEST-----
certificaterequestkey
-----END CERTIFICATE REQUEST-----", "adminContact" : {"title" : "mytitle", "firstName" : "myfirstname", "lastName" : "mylastname", "phoneNumber" : "X0000000", "emailAddress" : "test@example.com"}, "techContact" : {"title" : "mytitle", "firstName" : "myfirstname", "lastName" : "mylastname", "phoneNumber" : "000000000", "emailAddress" : "test@example.com"}, "productCode" : "ssl-geotrust-rapidssl-12m", "validationType" : "validateViaDns", "approverEmailAddress" : "postmaster@example.com", "autoRenew" : false}}' -i -X POST https://partner.http.net/api/ssl/v1/json/orderCreate

但是,如果我通过直接阅读csr文件来传递CSR,就像这样

authToken="Here'sMyAuthToken"
csr=$(<csr.csr)
curl --data-binary '{"authToken" : "'$authToken'", "order" : {"type" : "DomainValidatedCertificateOrder", "csr" : "'$csr'", "adminContact" : {"title" : "mytitle", "firstName" : "myfirstname", "lastName" : "mylastname", "phoneNumber" : "X0000000", "emailAddress" : "test@example.com"}, "techContact" : {"title" : "mytitle", "firstName" : "myfirstname", "lastName" : "mylastname", "phoneNumber" : "000000000", "emailAddress" : "test@example.com"}, "productCode" : "ssl-geotrust-rapidssl-12m", "validationType" : "validateViaDns", "approverEmailAddress" : "postmaster@example.com", "autoRenew" : false}}' -i -X POST https://partner.http.net/api/ssl/v1/json/orderCreate

它将给予以下错误。

curl: option -----END: is unknown
curl: try 'curl --help' or 'curl --manual' for more information

我已经发现了一个案例,其中有人有完全相同的问题,就像我在这里:
POST request containing CSR fails in Bash
用户使用jq软件包解决了这个问题。不幸的是,我不能在脚本应该运行的机器上安装这个软件包,因为我根本不允许安装任何软件包。有人能给予一个解决这个问题的建议吗?
提前感谢!

pgccezyw

pgccezyw1#

我一直有一个非常困难的时间张贴。我不断得到错误时,保存。
这是HTTP请求标头中带有Content-Type: application/json的请求和响应:

Content-Length: 540
Content-Type: application/json
Accept: application/json
Accept-Encoding: deflate, gzip, br
Host: eatled.com

BODY={"authToken": "$authToken","order": {"type": "DomainValidatedCertificateOrder","csr": "$csr","adminContact": {"title": "mytitle","firstName": "myfirstname","lastName": "mylastname","phoneNumber": "X0000000","emailAddress": "test@example.com"},"techContact": {"title": "mytitle","firstName": "myfirstname","lastName": "mylastname","phoneNumber": "000000000","emailAddress": "test@example.com"},"productCode": "ssl-geotrust-rapidssl-12m","validationType": "validateViaDns","approverEmailAddress": "postmaster@example.com","autoRenew": false}}

我删除了内容类型,这是请求和响应。
请注意头部是如何变为Content-Type: application/x-www-form-urlencoded的,以及服务器收到$_POST数据时JSON是如何出现在数据的KEY中的。当服务器看到表单数据头部时,它可能会尝试将请求当作表单来处理。这取决于API的编写情况。

Content-Length: 540
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Accept-Encoding: deflate, gzip, br
Host: eatled.com

$_POST
array (
  '{"authToken":_"$authToken","order":_{"type":_"DomainValidatedCertificateOrder","csr":_"$csr","adminContact":_{"title":_"mytitle","firstName":_"myfirstname","lastName":_"mylastname","phoneNumber":_"X0000000","emailAddress":_"test@example_com"},"techContact":_{"title":_"mytitle","firstName":_"myfirstname","lastName":_"mylastname","phoneNumber":_"000000000","emailAddress":_"test@example_com"},"productCode":_"ssl-geotrust-rapidssl-12m","validationType":_"validateViaDns","approverEmailAddress":_"postmaster@example_com","autoRenew":_false}}' => '',
)

这是你的curl代码,所有的转义码和选项都被重新组织了,因为你让它们产生了一个错误。这是经过测试的,并且可以工作。

curl  -i -H "Content-Type: application/json" -X POST http://eatled.com/receiveheader.php --data-binary "{\"authToken\": \"$authToken\",\"order\": {\"type\": \"DomainValidatedCertificateOrder\",\"csr\": \"$csr\",\"adminContact\": {\"title\": \"mytitle\",\"firstName\": \"myfirstname\",\"lastName\": \"mylastname\",\"phoneNumber\": \"X0000000\",\"emailAddress\": \"test@example.com\"},\"techContact\": {\"title\": \"mytitle\",\"firstName\": \"myfirstname\",\"lastName\": \"mylastname\",\"phoneNumber\": \"000000000\",\"emailAddress\": \"test@example.com\"},\"productCode\": \"ssl-geotrust-rapidssl-12m\",\"validationType\": \"validateViaDns\",\"approverEmailAddress\": \"postmaster@example.com\",\"autoRenew\": false}}"
klh5stk1

klh5stk12#

你在命令行中错误地引用了一些东西。你经常使用这种结构:

'{"somekey": "'$variable'"}'

这意味着你 * 没有 * 引用$somevariable,所以如果它包含空格,你将得到一个与你期望的命令不同的命令。你需要引用所有变量,所以上面的代码变成:

'{"somekey": "'"$variable"'"}'

完整的命令行是:

curl --data-binary '
  {
    "authToken" : "'"$authToken"'",
    "order" : {
      "type" : "DomainValidatedCertificateOrder",
      "csr" : "'"$csr"'",
      "adminContact" : {
        "title" : "mytitle",
        "firstName" : "myfirstname",
        "lastName" : "mylastname",
        "phoneNumber" : "X0000000",
        "emailAddress" : "test@example.com"
      },
      "techContact" : {
        "title" : "mytitle",
        "firstName" : "myfirstname",
        "lastName" : "mylastname",
        "phoneNumber" : "000000000",
        "emailAddress" : "test@example.com"
      },
      "productCode" : "ssl-geotrust-rapidssl-12m",
      "validationType" : "validateViaDns",
      "approverEmailAddress" : "postmaster@example.com",
      "autoRenew" : false
    }
  }
  ' -i -X POST https://partner.http.net/api/ssl/v1/json/orderCreate

您可以使用 here document 来简化操作,而不是尝试在命令行中嵌入所有内容。

curl -i -X POST --data-binary @- https://partner.http.net/api/ssl/v1/json/orderCreate <<EOF
{
  "authToken": "$authToken",
  "order": {
    "type": "DomainValidatedCertificateOrder",
    "csr": "$csr",
    "adminContact": {
      "title": "mytitle",
      "firstName": "myfirstname",
      "lastName": "mylastname",
      "phoneNumber": "X0000000",
      "emailAddress": "test@example.com"
    },
    "techContact": {
      "title": "mytitle",
      "firstName": "myfirstname",
      "lastName": "mylastname",
      "phoneNumber": "000000000",
      "emailAddress": "test@example.com"
    },
    "productCode": "ssl-geotrust-rapidssl-12m",
    "validationType": "validateViaDns",
    "approverEmailAddress": "postmaster@example.com",
    "autoRenew": false
  }
}
EOF

现在你不需要那些引用的技巧了。
下面是我对上述解决方案的测试:

#!/bin/bash

# Use some sort of http debugging service to verify the content
# of the request.
url="https://eny65dku43a4g.x.pipedream.net"

# Create an example CSR
openssl req new -nodes \
  -keyout req.key \
  -out req.csr \
  -subject '/O=Example$Organization+Inc,CN=example.com'

csr=$(<req.csr)
authToken='example+password$here'

curl -i -X POST "$url" --data-binary @- <<EOF
{
  "authToken": "$authToken",
  "order": {
    "type": "DomainValidatedCertificateOrder",
    "csr": "$csr",
    "adminContact": {
      "title": "mytitle",
      "firstName": "myfirstname",
      "lastName": "mylastname",
      "phoneNumber": "X0000000",
      "emailAddress": "test@example.com"
    },
    "techContact": {
      "title": "mytitle",
      "firstName": "myfirstname",
      "lastName": "mylastname",
      "phoneNumber": "000000000",
      "emailAddress": "test@example.com"
    },
    "productCode": "ssl-geotrust-rapidssl-12m",
    "validationType": "validateViaDns",
    "approverEmailAddress": "postmaster@example.com",
    "autoRenew": false
  }
}
EOF

相关问题