node.js - 如何为 RESTlet 构造 OAuth 授权标头?
问题描述
我无法创建 OAuth 授权标头。我不断收到 INVALID_LOGIN_ATTEMPT 并且我无法找到我做错了什么。
我已按照此处的说明创建授权标头。
我的完整工作流程:
- 创建 hello world SuiteScript 2.0 restlet
- 上传到我的 NetSuite 帐户
- 创建集成记录
- 创建部署
- 创建具有权限的角色:
- 访问令牌管理 - 完整
- 使用访问令牌登录 - 完整
- 用户访问令牌 - 完整
- 网络服务 - 完整
- 从上一步创建用户并分配角色
- 创建集成并启用基于令牌的身份验证
- 发出新的访问令牌
RESTlet URL 是从部署详细信息中复制/粘贴的,帐户 ID 是从设置/集成/Web 服务首选项中提取的
这是我的虚拟客户:
const https = require('https');
const crypto = require('crypto');
function generateNonce() {
return crypto.randomBytes(16).toString("hex");
}
const NETSUITE_ACCOUNT_ID = 'tstdrv00000000';
const BASE_URL = `https://${NETSUITE_ACCOUNT_ID}.restlets.api.netsuite.com/app/site/hosting/restlet.nl`;
const HTTP_METHOD = 'GET';
const SCRIPT_ID = '546';
const SCRIPT_DEPLOYMENT_ID = '1';
const OAUTH_VERSION = '1.0';
const TOKEN_ID = "0";
const TOKEN_SECRET = "0";
const CONSUMER_KEY = "0";
const CONSUMER_SECRET = "0";
const OAUTH_NONCE = generateNonce();
const TIMESTAMP = Date.now();
function createSignature() {
const key = `${CONSUMER_SECRET}&${TOKEN_SECRET}`;
const data = `deploy=${SCRIPT_DEPLOYMENT_ID}&oauth_consumer_key=${CONSUMER_KEY}&oauth_nonce=${OAUTH_NONCE}&oauth_signature_method=HMAC-SHA256&oauth_timestamp=${TIMESTAMP}&oauth_token=${TOKEN_ID}&oauth_version=${OAUTH_VERSION}&script=${SCRIPT_ID}`;
const payload = `${HTTP_METHOD}&${encodeURIComponent(BASE_URL)}&${encodeURIComponent(data)}`;
const hmac = crypto.createHmac('sha256', key);
const digest = hmac.update(payload).digest('hex');
const signature = new Buffer(digest).toString('base64');
return signature;
}
let OAuth = `OAuth oauth_signature="${createSignature()}", oauth_version="1.0", oauth_nonce="${OAUTH_NONCE}", oauth_signature_method="HMAC-SHA256", oauth_consumer_key="${CONSUMER_KEY}", oauth_token="${TOKEN_ID}", oauth_timestamp="${TIMESTAMP}", realm="${NETSUITE_ACCOUNT_ID}"`;
const request = new Promise((resolve, reject) => {
const responsePayload = [];
const request = https.get(
`${BASE_URL}?script=${SCRIPT_ID}&deploy=${SCRIPT_DEPLOYMENT_ID}`,
{
headers: {
"Content-Type": "application/json",
"Authorization": OAuth
},
},
(response) => {
console.log("statusCode: ", response.statusCode);
console.log("headers: ", response.headers);
response.setEncoding('utf8');
response.on('data', chunk => {
responsePayload.push(chunk);
});
response.on('end', () => {
try {
resolve(JSON.parse(responsePayload.join()));
} catch (error) {
resolve(responsePayload);
}
});
}
);
request.on('error', error => {
reject(error);
});
request.end();
});
request
.then((response => console.log("OK", response)))
.catch(e => console.error("Error", e));
解决方案
INVALID_LOGIN_ATTEMPT
此错误表示 OAuth 标头中存在问题。当 OAuth 标头中的 nonce、消费者密钥、令牌或签名无效时,可以返回它。
我相信你的签名不正确。它应该在您的可变负载上具有与您的 xhr 请求相同的 url/参数来生成签名:
const payload = '${HTTP_METHOD}&${BASE_URL}?script=${SCRIPT_ID}&deploy=${SCRIPT_DEPLOYMENT_ID}&${encodeURIComponent(data)}';
const request = new Promise((resolve, reject) => {
const responsePayload = [];
const request = https.get(
'${BASE_URL}?script=${SCRIPT_ID}&deploy=${SCRIPT_DEPLOYMENT_ID}&${encodeURIComponent(data)}',
{
headers: {
"Content-Type": "application/json",
"Authorization": OAuth
},
},
...
推荐阅读
- css - 使用 CSS 创意制作 SVG 动画?
- database - VM 上的持久磁盘与 Kubernetes 集群的托管数据库
- excel - 对于循环删除行,循环正在跳过行
- python - 如何在 pyglet 中使用调度函数为变量赋值?
- sql - 在where子句中查询日期和具体时间
- c# - Xamarin Forms Span 保留空白
- javascript - 如何将输入添加到现有 url
- javascript - 在 html 表中,使用 jQuery 将每个数据行的第一个单元格更改为 ,而不是元素?
- javascript - Google Map APIs - 结合地理位置和集群标记
- angular - 从指令更改区域设置引用的无效状态