javascript - 使用 SuiteScript 2.x 为 DocuSign API 集成创建 JWT

标签 javascript jwt docusignapi netsuite suitescript2.0

我正在为 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/

相关文章:

javascript - 获取下拉框中所选项目的id属性

Java - Auth0 JWT 验证 - 这是否正确?

javascript - 没有字体颜色的下划线颜色 Word Web 插件

javascript - JS : Most optimized way to remove a filename from a path in a string?

javascript - 计算器功能不起作用,显示函数未定义

javascript - 尝试在 Node 中实现 JWT 身份验证。在 protected route 未经授权

java - Dropwizard JWT 工作流程

pdf - Docusign 在所有页面上重复签名标签

javascript - Salesforce:使用机会所有者的经理自动填充 DocuSign 收件人

grails - 在 Grails 中下载 Docusign PDF,文件损坏