我有代码设置,可以使用基于令牌的身份验证在 Node JS 中调用 Netsuite Rest API -(使用外部 id 进行更新插入)。 我可以说该代码正在运行,因为 API 返回 204 响应代码并且通过它创建了 netsuite 记录。但是,API 也会间歇性地返回 401 响应代码。 几乎一半没有。 API 调用返回 401 代码的次数。
事实上,当在 Postman 中尝试相同的有效负载时(从上述方法返回 401 响应),它起作用并返回 204。我不知道为什么它在以编程方式运行时会间歇性地工作。
另外,不确定这是否重要,但仅供参考,我正在 Cloud Functions (GCP) 中运行代码。
代码:
function upsertOperation(externalId, body) {
const baseUrl = `https://${NETSUITE_ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/record/v1/${RESOURCE}`;
const oauthNonce = crypto.randomBytes(32).toString('hex');
const oauthTimestamp = Math.floor(Date.now() / 1000);
const oauthSignatureMethod = 'HMAC-SHA256';
const oauthVersion = '1.0';
const realm = `${REALM}` // Note: Replaced space with underscore and lower case letters with upper case letters in netsuite account id. Not provided exatct value here.
const oauthParameters = {
oauth_consumer_key: CONSUMER_KEY,
oauth_token: ACCESS_TOKEN,
oauth_nonce: oauthNonce,
oauth_timestamp: oauthTimestamp,
oauth_signature_method: oauthSignatureMethod,
oauth_version: '1.0'
};
const sortedParameters = Object.keys(oauthParameters)
.sort()
.map((key) => `${key}=${oauthParameters[key]}`)
.join('&');
const signatureBaseString = `PUT&${encodeURIComponent(baseUrl+'/eid:' + externalId)}&${encodeURIComponent(sortedParameters)}`;
const signingKey = `${CONSUMER_SECRET}&${ACCESS_TOKEN_SECRET}`;
const hmac = crypto.createHmac('sha256', signingKey);
hmac.update(signatureBaseString);
const oauthSignature = hmac.digest('base64');
const headers = {
'Prefer': 'transient',
'Content-Type': 'application/json',
'Authorization': `OAuth realm="${realm}",oauth_signature="${oauthSignature}",oauth_nonce="${oauthNonce}",oauth_signature_method="${oauthSignatureMethod}",oauth_consumer_key="${CONSUMER_KEY}",oauth_token="${ACCESS_TOKEN}",oauth_timestamp="${oauthTimestamp}",oauth_version="${oauthVersion}"`
};
fetch(baseUrl+'/eid:' + externalId, {
method: 'PUT',
headers: headers,
body: JSON.stringify(body),
redirect: 'follow'
})
.then((response) => response.json())
.then((data) => {
console.log('data: ' + JSON.stringify(data));
})
.catch((error) => {
console.error('Error upsertOperation:', error);
});
}
这是一个理论,无论其价值如何......
来自 https://oauth.net/core/1.0/#nonce
除非服务提供商另有规定,时间戳以自 1970 年 1 月 1 日 00:00:00 GMT 起的秒数表示。时间戳值必须是正整数,并且必须等于或大于先前请求中使用的时间戳。
IF您正在从不同时间的两个系统发出请求,例如:GCP云功能和您自己的计算机通过Postman,然后您可能会遇到这样的情况,其中某些请求的时间戳早于之前的请求,根据 Oauth 规范,该请求将被拒绝。
如果没有来自不同系统的请求,则可能是您使用的系统与 NetSuite 服务器的时间不同。我之前已经看到这是一个问题(示例),但不确定这是否会导致间歇性问题。我想如果时间戳与系统时间的比较包括舍入,并且系统时间之间的差异接近舍入截止点,则可以。
另一种可能性是 GCP 几乎同时或在很短的时间内运行两个实例。一个实例启动,另一个实例以较晚的时间戳启动,但首先进行 http 调用。在这种情况下,第一个触发的请求可能会因其较早的时间戳而被拒绝。