用于更新插入的 Netsuite Rest API 间歇性地响应 401 响应代码

问题描述 投票:0回答:1

我有代码设置,可以使用基于令牌的身份验证在 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);
    });
}
node.js oauth netsuite oauth-1.0a netsuite-rest-api
1个回答
0
投票

这是一个理论,无论其价值如何......

来自 https://oauth.net/core/1.0/#nonce

除非服务提供商另有规定,时间戳以自 1970 年 1 月 1 日 00:00:00 GMT 起的秒数表示。时间戳值必须是正整数,并且必须等于或大于先前请求中使用的时间戳。

IF您正在从不同时间的两个系统发出请求,例如:GCP云功能和您自己的计算机通过Postman,然后您可能会遇到这样的情况,其中某些请求的时间戳早于之前的请求,根据 Oauth 规范,该请求将被拒绝。

如果没有来自不同系统的请求,则可能是您使用的系统与 NetSuite 服务器的时间不同。我之前已经看到这是一个问题(示例),但不确定这是否会导致间歇性问题。我想如果时间戳与系统时间的比较包括舍入,并且系统时间之间的差异接近舍入截止点,则可以。

另一种可能性是 GCP 几乎同时或在很短的时间内运行两个实例。一个实例启动,另一个实例以较晚的时间戳启动,但首先进行 http 调用。在这种情况下,第一个触发的请求可能会因其较早的时间戳而被拒绝。

© www.soinside.com 2019 - 2024. All rights reserved.