0

我正在尝试通过 Xero API、一个简单的 bash 脚本和 cURL 与我的 Xero 帐户进行通信。另外,我正在使用 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(我称之为verbURLParams. 我确保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 没有报告操作问题,而且许多其他人似乎也经历过这种情况。

4

1 回答 1

1

最后一步是直接对 oauth_signature 值进行 url 编码,然后再将其添加到 Authorization 标头中。一旦你这样做了,你就会变成金子。

于 2018-04-19T20:46:24.377 回答