Xero Private App 使用 cURL 获取发票 - 无法验证签名/错误 500?

Xero Private App to get invoice with cURL- failed to validate signature / error 500?

我正在尝试通过 Xero API、一个简单的 bash 脚本和 cURL 与我的 Xero 帐户通信。此外,我正在使用 Xero Private App,这意味着我已经生成了一个 public/private 密钥对,public 密钥上传到 Xero 并且在我的程序中使用了私有应用程序。

按照此处的建议生成密钥对 https://developer.xero.com/documentation/api-guides/create-publicprivate-key:

openssl genrsa -out privatekey.pem 1024
openssl req -new -x509 -key privatekey.pem -out publickey.cer -days 1825
openssl pkcs12 -export -out public_privatekey.pfx -inkey privatekey.pem -in publickey.cer

以下是我的代码和思路。

首先,我为 OAuth 请求创建参数。我知道 Xero Private Apps 使用 OAuth1.0a 并且需要用 RSA-SHA1 签名。

oauth_consumer_key="my_key"
oauth_nonce="$(($(date +%s) - 10000))"
oauth_signature_method="RSA-SHA1"
oauth_timestamp="$(date +%s)"
oauth_token="my_key"
oauth_version="1.0"

现在,我专注于生成 OAuth 签名,如 https://oauth1.wp-api.org/docs/basics/Signing.html 中所述。我确保使用 Method(我称之为 verb)、URLParams 创建一个基本字符串。我确保 Params 按名称排序。此外,在与 &.

连接之前,我 URL_encode 这些值
verb=GET
url=https://api.xero.com/api.xro/2.0/Invoices/243216c5-369e-4056-ac67-05388f86dc81
params=oauth_consumer_key=$oauth_consumer_key\&oauth_nonce=$oauth_nonce\&oauth_signature_method=$oauth_signature_method\&oauth_timestamp=$oauth_timestamp\&oauth_token=$oauth_token\&oauth_version=$oauth_version
baseString=$(urlencode $verb)\&$(urlencode $url)\&$(urlencode $params)

echo $baseString returns GET&https%3A%2F%2Fapi.xero.com%2Fapi.xro%2F2.0%2FInvoices%2Fe4d08842-29fc-4228-8227-8661e0f93ea3&oauth_consumer_key%*%26oauth_nonce%3D1523125307%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1523135308%26oauth_token%*%26oauth_version%3D1.0

urlencode 函数:

function urlencode() {
    echo -n "" | perl -MURI::Escape -ne 'print uri_escape($_)'
}

我使用 OpenSSL 签署 baseString,如下所示。

oauth_signature=$(echo -n "$baseString" | openssl dgst -sha1 -sign "C:\path\to\keys\privatekey.pem" | openssl enc -A -base64)
echo $oauth_signature

现在,我使用相同的参数创建授权 header,但包括刚刚生成的签名。

auth_header="Authorization: OAuth oauth_consumer_key=\"$oauth_consumer_key\", oauth_nonce=\"$oauth_nonce\", oauth_signature=\"$oauth_signature\", oauth_signature_method=\"$oauth_signature_method\", oauth_timestamp=\"$oauth_timestamp\", oauth_token=\"$oauth_token\", oauth_version=\"$oauth_version\"" 

echo $auth_header returns Authorization: OAuth oauth_consumer_key="*", oauth_nonce="1523124975", oauth_signature="*", oauth_signature_method="RSA-SHA1", oauth_timestamp="1523134975", oauth_token="*", oauth_version="1.0"

最后,我通过 cURL 发送 GET 请求以获取特定发票。

curl -G "https://api.xero.com/api.xro/2.0/Invoices/243216c5-369e-4056-ac67-05388f86dc81" -H "$auth_header"

我收到...

oauth_problem=signature_invalid&oauth_problem_advice=Failed%20to%20validate%20signature

我期望 JSON 对发票的回应或告诉我发票不存在的东西。

我觉得我的步骤是正确的。好吧,我猜签名有问题。要么是它签名的东西格式不正确,要么是 RSA-SHA1 有问题?我不知所措。如果有任何反馈,我将不胜感激。

编辑:感谢@rustyskates,我修正了一些错误,但是,现在我得到: <ApiException xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ErrorNumber>500</ErrorNumber> <Type>UnknownErrorException</Type> <Message>An error occurred in Xero. Check the API Status page http://status.developer.xero.com for current service status. Contact the API support team at api@xero.com for more assistance.</Message> </ApiException> 这看起来仍然是个问题,因为 Xero 没有报告操作问题,而且许多其他人似乎也遇到过这个问题。

最后一步是 url-encode oauth_signature 值,然后直接将其添加到授权 header。一旦你做到了,你就会变成金子。