You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Node.js调用NetSuite Restlet出现403(InvalidSignature)错误

NetSuite Restlet POST请求403 InvalidSignature问题
  • 通过Node.js调用部署好的NetSuite Restlet脚本创建Customer记录时,返回403错误
  • 相同请求在Postman中可成功执行,且同一OAuth授权逻辑调用NetSuite REST API的PUT请求也能正常工作
  • NetSuite登录审计日志中错误详情显示为InvalidSignature

对应的Node.js代码

function upsertUsingRestlet(body, callbackFn) {

  const baseUrl = `https://${NETSUITE_ACCOUNT_ID}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=${SCRIPT_ID}&deploy=${DEPLOYMENT_ID}`;
  const oauthSignatureMethod = 'HMAC-SHA256';
  const oauthVersion = '1.0';
  const oauthNonce = crypto.randomBytes(32).toString('hex');
  const oauthTimestamp = Math.floor(Date.now() / 1000);

  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 = `POST&${encodeURIComponent(baseUrl)}&${encodeURIComponent(sortedParameters)}`;
  const signingKey = `${CONSUMER_SECRET}&${ACCESS_TOKEN_SECRET}`;
  const hmac = crypto.createHmac('sha256', signingKey);
  hmac.update(signatureBaseString);
  let oauthSignature = hmac.digest('base64');
  oauthSignature = encodeURIComponent(oauthSignature);

  const headers = {
    'Prefer': 'transient',
    'Content-Type': 'application/json',
    'Authorization': `OAuth realm="${REALM}",oauth_nonce="${oauthNonce}",oauth_signature_method="${oauthSignatureMethod}",oauth_consumer_key="${CONSUMER_KEY}",oauth_token="${ACCESS_TOKEN}",oauth_timestamp="${oauthTimestamp}",oauth_version="${oauthVersion}",oauth_signature="${oauthSignature}"`
  };

  fetch(baseUrl, {
    'method': 'POST',
    'headers': headers,
    'body': body,
    'redirect': 'follow'
  })
    .then((response) => response)
    .then((data) => {
      callbackFn(data.status);
    })
    .catch((error) => {
      console.error('Error upsertOperation:', error);
    });
}

Restlet脚本部署配置

截图展示了Restlet的部署配置界面,包含脚本ID、部署ID的设置项,以及对应的访问权限配置内容。

内容的提问来源于stack exchange,提问作者user19976880

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 21:12:57