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

时间:2018-04-07 19:24:41

标签: bash curl openssl xero-api oauth-1.0a

我正在尝试通过Xero API与我的Xero帐户进行通信,这是一个简单的bash脚本和cURL。此外,我正在使用Xero私有应用程序,这意味着我已经生成了一个公钥/私钥对,上传到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返回 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 "$1" | 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

现在,我使用相同的参数创建Authorization标头,但包括刚刚生成的签名。

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返回 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不会报告操作问题,而且许多其他人似乎也经历过这种情况。

1 个答案:

答案 0 :(得分:1)

最后一步是在将oauth_signature值添加到Authorization标头之前直接对其进行url-encode。一旦你这样做,你就会变得金黄。