Netsuite OAuth Not Working

后端 未结 2 999
广开言路
广开言路 2021-01-03 04:40

I\'ve tried implementing Netsuite\'s OAuth Example, as illustrated here: https://netsuite.custhelp.com/app/answers/detail/a_id/42165. I\'ve posted it directly below so you

相关标签:
2条回答
  • 2021-01-03 04:43

    Netsuite's node samples use oauth-1.0a

    https://netsuite.custhelp.com/app/answers/detail/a_id/42171

    and their sample from https://netsuite.custhelp.com/app/answers/detail/a_id/42172/

    is what I've had in production for a couple of years and works well.

    var Promise = require('bluebird');
    var request = require('request');
    var crypto = require('crypto');
    var OAuth = require('oauth-1.0a');
    var Agent = require('https').Agent;
    //var debug = require('debug')('kotn-ns');
    
    
    function promiseTry(pSrc, maxTries, minDelay, maxDelay, canRetry){ //NS prone to spurious failures due to overloading
        return new Promise(function(resolve, reject){
    
            minDelay = minDelay || 0;
            var delaySize = maxDelay - minDelay;
            var t = function(){ return Math.floor(Math.random()* delaySize)+ minDelay;};
            var firstReason = null;
    
            function doRetry(triesLeft){
    
                pSrc().then(function(data){
                    resolve(data);
                }).catch(function(reason){
                    if(!firstReason) firstReason = reason;
                    console.error('in retry error with '+reason.toString());
                    if(triesLeft  && canRetry(reason)) setTimeout(function(){ doRetry(triesLeft-1);}, t());
                    else reject(firstReason);
                });
            }
            doRetry(maxTries -1);
        });
    }
    
    function hasReason(msg, reasons){
        for(var i = 0; i< reasons.length;i++){
            if(msg.indexOf(reasons[i]) != -1) return true;
        }
        return false;
    }
    
    var agentPool = {};
    function getAgent(accountId, tokenId){
        var agentKey = accountId+'::'+ tokenId;
        var agent = agentPool[agentKey];
        if(!agent){
            console.log('new agent for '+agentKey)
            agent = new Agent({
                keepAlive:false,
                maxSockets:5
            });
            agentPool[agentKey] = agent;
        }
        return agent;
    }
    
    
    /**
     * [RESTHandler description]
     * @param {options} options {accountId, consumerKey,consumerSecret,tokenId,tokenSecret}
     */
    function RESTHandler(options) {
    
    
    
        var config = Object.assign({
            maxTries:3,
            minRetryDelay: 800,
            maxRetryDelay:30000,
            canRetry: function(reason){
                var reasonText =  reason.message || JSON.stringify(reason);
                if(hasReason(reasonText, ['ECONNRESET', 'ESOCKETTIMEDOUT','ETIMEDOUT', 'SSS_REQUEST_LIMIT_EXCEEDED'])) {
                    console.error('retrying because: '+reasonText);
                    return true;
                }
                console.error('no retry with: '+reasonText);
                return false;
            }
        }, options);
    
        var oauth = OAuth({
            consumer: {
                key: config.consumerKey,
                secret: config.consumerSecret
            },
            signature_method: 'HMAC-SHA1',
            parameter_seperator: ',',
            hash_function: function(base_string, key) {
                return crypto.createHmac('sha1', key).update(base_string).digest('base64');
            }
        });
        var token = {
            key: config.tokenId,
            secret: config.tokenSecret
        };
    
        function makeRequest(url, method, payload) {
            var requestData = {
                url: url,
                method: method
            };
            if(payload){
                requestData.body = payload;
            }
    
            var headers = oauth.toHeader(oauth.authorize(requestData, token));
            headers.Authorization += ',realm="' + config.accountId + '"';
            headers.authorization = headers.Authorization;
            delete headers.Authorization;
            headers['content-type'] = 'application/json';
            headers['accept'] = 'application/json';
    
            //console.log(JSON.stringify(headers, null, '  '));
            requestData.headers = headers;
            Object.assign(requestData, {
                pool:getAgent(config.accountId, config.tokenId),
                timeout : 30000,
                strictSSL : true
            });
    
            // requestData.json = true;
    
            // return new Promise(function(resolve){
            //     resolve({'headers' : 'done'});
            // });
    
    
    
            var processRequest = function(){
                return new Promise(function(resolve, reject) {
                    request(requestData, function(error, response, body) {
                        if(error){
                            console.error('error calling: '+ requestData.url);
                            console.error(error);
                            reject((error instanceof Error) ? error : new Error(JSON.stringify(error)));
                            return;
                        }
                        if(!body || !(/"success"/).test(body)) {
                            console.log(method +' '+ response.statusCode +' '+ url +'\n\t'+body);
                            reject(new Error(body || 'unexpected error'));
                            return;
                        }
                        try{
                            resolve(JSON.parse(body));
                        }catch(e){
                            console.trace(e);
                            reject(e);
                        }
                    });
                });
            };
            return promiseTry(processRequest, config.maxTries, config.maxRetryDelay, config.minRetryDelay, config.canRetry);
        }
    
        return{
            get: function(url){
                return makeRequest(url, 'GET');
            },
            put: function(url, data){
                return makeRequest(url, 'PUT', data);
            },
            post: function(url, data){
                return makeRequest(url, 'POST', data);
            },
            destroy : function(){
                //nsAgent.destroy();
            }
        };
    }
    module.exports = RESTHandler;
    
    0 讨论(0)
  • 2021-01-03 05:07

    EDIT: Just published an npm module which should make things easier: https://www.npmjs.com/package/nsrestlet


    Was able to get some code working after hunting through GitHub Code commits. Still, bknights response is really good.

    Here's what I got working.

    Assuming you have Node.js and npm installed, run:

    npm install request
    npm install oauth-1.0a@1.0.1
    

    It's really important that it's version 1.0.1.

    Once you have that, this code should work:

    /*
        =================    REQUIRED USER ACCOUNT INFORMATION    ==============================================
    */
    
    var accountID = 'PUT ACCOUNT ID HERE';
    
    var token = {
        public: 'PUT TOKEN KEY HERE',
        secret: 'PUB TOKEN SECRET HERE'
    };
    
    var consumer = {
        public: 'PUT CONSUMER KEY HERE',
        secret: 'PUT CONSUMER SECRET HERE'
    };
    
    //use the full restlet URL, not the rest.netsuite.com URL
    //for example, https://YOURACCOUNTNUMBER.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=SCRIPTNUMBER&deploy=DEPLOYNUMBER
    var restlet_url = 'PUT YOUR RESTLET URL HERE';
    
    /*
        =========================================================================================================
    */
    
    //REQUIRED NPM MODULES
    const request = require('request');
    const OAuth   = require('oauth-1.0a');      //version 1.0.1, don't do version 1.1.0
    
    //SET UP THE OAUTH OBJECT
    var oauth = OAuth({
        consumer: consumer,
        signature_method: 'HMAC-SHA256'         //you can also use HMAC-SHA1 but HMAC-SHA256 is more secure (supposedly)
    });
    
    //SET UP THE REQUEST OBJECT
    var request_data = {
        url: restlet_url,
        method: 'POST',
    };
    
    //GET THE AUTHORIZATION AND STICK IT IN THE HEADER, ALONG WITH THE REALM AND CONTENT-TYPE
    var authorization = oauth.authorize(request_data, token);
    var header = oauth.toHeader(authorization);
    header.Authorization += ', realm="' + accountID + '"';
    header['content-type'] = 'application/json';
    
    //MAKE THE REQUEST
    request({
        url: request_data.url,
        method: request_data.method,
        headers: header,
        json: {
            message: "test123"                  //this is your payload
        }
    }, function(error, response, body) {
        if(error)
        {
            console.log(error);
        }
        else
        {
            console.log(body);
        }
    });
    

    If anybody has any problems with this code, leave a response and I'll do my best to help.

    0 讨论(0)
提交回复
热议问题