Using SuiteScript with OAuth 2.0

To make an authorized request with SuiteScript, you must create and send a JWT token to obtain an access token. The access token will be used as a header in the HTTPs request.

The following example shows the basic structure of making an OAuth 2.0 authorized request.

           * Create a JWT signed with the private key of the certificate.
 */
const jwt = createJWT({ /* ... */ });
 
 
/**
 * Send the JWT to an endpoint to obtain an access token.
 * The access token can be cached and used repeatedly, but it must be refreshed at certain point.
 * The lifetime of the token is typically few minutes or few hours at most.
 */
const accessToken = createAccessToken({ jwt });
 
/**
 * Make an HTTPs request.  Access token goes in as a header.
 */
const response = https.post({
    /* ... */
    headers: { Authorization: `Bearer ${accessToken}` },
}); 

        

Creating JWT tokens

JWT tokens can contain user information, permissions, or other information, depending on what the access token endpoint requires. The following example shows how to connect to another NetSuite account. For more information, see The Request Token Structure.

            const jwt = createJWT({
    headers: {
        "typ": "JWT",
        "alg": "PS256",  // Depends on the certificate and the hash algorithm you're using.
        "kid": "...",  // Certificate ID in the target account from OAuth 2.0 Client Credentials (M2M) Setup
    },
    payload: {
        "iss": "...",  // Client ID of the Integration in the target account
        "scope": "restlets",
        "aud": "https://<accountID>/services/rest/auth/oauth2/v1/token",
        "iat": Math.round(new Date().getTime() / 1000),
        "exp": Math.round(new Date().getTime() / 1000) + 120,  // in this case, the access token will be valid 120 seconds
    },
}); 

          

The following example code shows how to build the JWT token and sign it using the private key of the certificate.

            define(["N/encode", "N/crypto/certificate"], (encode, mCryptoCert) =>
{
    function createJWT({ headers, payload })
    {
        const segments = [
            base64(JSON.stringify(headers)),
            base64(JSON.stringify(payload)),
        ];
        const signature = sign(segments.join("."), certificate, algorithm);
        return [...segments, signature].join(".");
    }
 
    function sign(payload)
    {
        let signer = mCryptoCert.createSigner({ certId: "custcertificate_oauth2_pss", algorithm: mCryptoCert.HashAlg.SHA256 });
        signer.update(payload);
        return signer.sign({ outputEncoding: encode.Encoding.BASE_64_URL_SAFE }).replace(/=/g, "");
    }
 
    function base64(s)
    {
        return encode.convert({
            string: s,
            inputEncoding: encode.Encoding.UTF_8,
            outputEncoding: encode.Encoding.BASE_64_URL_SAFE,
        }).replace(/=/g, "");
    }
}); 

          

Note that if you are using an ECDSA certificate, N/crypto/certificate#Signer.sign() returns by default a signature in ASN.1 DER format. For JWT tokens, you need a raw format. In that case, you need to add useRawFormatForECDSA parameter. See Signer.sign(options).

            signer.sign({
    outputEncoding: encode.Encoding.BASE_64_URL_SAFE,
    useRawFormatForECDSA: true
}).replace(/=/g, ""); 

          

Obtaining access tokens

To obtain an access token, you must perform a request to an OAuth endpoint. To perform a request to another NetSuite account, use the same URL in aud field of your JWT token. For more information, see POST Request to the Token Endpoint and the Access Token Response.

            function createAccessToken(jwt)
{
    const response = https.request({
        method: "POST",
        url: "https://<accountID>/services/rest/auth/oauth2/v1/token",
        body: {
            grant_type: "client_credentials",
            client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
            client_assertion: jwt,
        }
    });
    if (response.code !== 200) {
        throw new Error(`${response.code}\n${response.body}`);
    }
    return JSON.parse(response.body).access_token;
} 

          

Related Topics

General Notices