我正在为 DocuSign 更新 NetSuite 集成以将所有脚本转换为 SuiteScript 2.0 并更新身份验证以使用 JWT 授权方法,因为目前的方法看起来将在几周内被新应用程序弃用,并且完全是明年的某个时候。不过,我确实有几个问题无法回答。
对于初学者来说,在为正文设置 IAT 和 EXP 值时,我是根据当前服务器时间获取此值(根据帐户数据中心恰好所在的时区而有所不同),还是应该基于取而代之的是 UTC 时间?在这个问题上,文档对我来说似乎不够清楚。
此外,我不清楚如何着手创建签名。除了上述问题之外,检索和准备必要的数据不是问题。但是,与我在创建签名时看到的示例相比,根据我在 2.0 模块中看到的可用内容安排要编码的数据似乎不太一致。例如,这是我所见的近似值:
var header = { typ : "JWT" , alg : "RS256" };
var body = { iss : "abc123" , sub : "def456" , iat : 123456789 , exp : 123456789 + (60 * 60) , scope : "signature" };
var encHeader = base64UrlEncode(JSON.stringify(header));
var encBody = base64UrlEncode(JSON.stringify(body));
// the key pairs are stored elsewhere, and the functions represent a way to retrieve the key contents
var publickKey = retrievePublicKey();
var privateKey = retrievePrivateKey();
var signature = RS256Encode(
encHeader + "." + encBody ,
publicKey ,
privateKey
);
这些示例显示了不同的加密函数,它们都以与上述相同的方式接收三个参数。然而,当查看 native SuiteScript 2.0 模块中可用的内容时,我没有看到任何可比性。我看到加密模块(它似乎被拉入其他模块)确实有能力执行所需的 RSA SHA256 编码,但不太确定如何确保所有部分都正确地放在一起。
我已经在 https://jwt.io/ 查看了用于创建 JWT 的 JavaScript 库,但我没有尝试将节点模块合并到 SuiteScript 项目中的经验,如果可能的话。
那么,有没有一种方法可以在 SuiteScript 中原生构建 JWT,或者我是否必须找到一种方法来在脚本中引用节点模块?
-- 编辑 --
好的,看来我可以使用“异步模块定义”(AMD) 通过创建 JSON 配置文件并将以下内容添加到脚本文件的 JSDoc header 来将模块导入脚本:
*@NAmdConfig /path/to/myModule.json
我想既然我需要它是一个相对路径,因为这个项目将分发给其他帐户,如果 JSON 配置文件在同一目录中,这样的事情应该有效:
*@NAmdConfig ./nodeModules.json
但是我花了很多时间来确定究竟如何设置 JSON 配置。我似乎无法找到任何真正有助于确定如何正确构建它的东西。最大的问题是确定模块是 AMD 还是非 AMD,如果是非 AMD,是否尝试导入 CJS 部分或 ESM 部分下的脚本。
对于任何其他引用,我使用 NPM 安装了 jose 模块,因为它与 JavaScript/Node 兼容并且具有我需要的加密方法。
npm install jose
现在,它在源项目中的路径如下所示:
SuiteScripts/Project_Name/lib/node_modules/jose
将引用模块的脚本文件位于此路径下:
SuiteScripts/Project_Name/lib
最佳答案
/**
*@NApiVersion 2.x
*/
define(['N/encode', 'N/crypto/certificate'], function(encode, cert){
function signIt(payload, ttl){
if(typeof payload.exp == 'undefined'){
var secondsSinceEpoch = Math.round(Date.now() / 1000);
var expAt = secondsSinceEpoch + (ttl || 60);
payload["exp"] = expAt;
payload["iat"] = secondsSinceEpoch;
}
log.debug({
title:'payload',
details: JSON.stringify(payload)});
var header = encode.convert({
string: JSON.stringify({
type:'JWT',
alg:'RS256'
}),
inputEncoding: encode.Encoding.UTF_8,
outputEncoding: encode.Encoding.BASE_64_URL_SAFE
}).replace(/=+$/, '');
var body = encode.convert({
string: JSON.stringify(payload),
inputEncoding: encode.Encoding.UTF_8,
outputEncoding: encode.Encoding.BASE_64_URL_SAFE}).replace(/=+$/, '');
var signer = cert.createSigner({
certId:'custcertificate_sample', //from Setup -> Company -> Certificates
algorithm: cert.HashAlg.SHA256
});
signer.update(header +'.'+ body);
var sig = signer.sign({
outputEncoding:encode.Encoding.BASE_64_URL_SAFE
}).replace(/=+$/, '');
return [header, body, sig].join('.');
}
return {
signIt: signIt
}
});
上传的 key 生成如下:
openssl genrsa -out private.pem 4096
openssl rsa -in private.pem -out public.pem -pubout
openssl req -key private.pem -new -x509 -days 3650 -subj "/C=CA/ST=Courtenay/O=Rule of Tech/OU=Information unit/CN=jwt.kotn.com" -out cert.pem
然后我使用文本编辑器连接来自 cert.pem 和 private.pem 的证书和私钥:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
关于javascript - 使用 SuiteScript 2.x 为 DocuSign API 集成创建 JWT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68597628/