Jsforce: Trying to refresh access token

Created on 3 Jul 2017  路  4Comments  路  Source: jsforce/jsforce

I am working on a Salesforce OAuth app, where I have some user's SalesForce account's

  • accessToken
  • refreshToken
  • instanceUrl

and the I do this and query for some data in his account.

var conn = new jsforce.Connection({
  instanceUrl : '<your Salesforce server URL (e.g. https://na1.salesforce.com) is here>',
  accessToken : '<your Salesforrce OAuth2 access token is here>'
});

But it only works till the access_token is valid.
I want that if it expires then it will get refreshed automatically or some event will trigger which will return the refreshed accessToken.

So, I tried this.

var conn = new jsforce.Connection({
  instanceUrl : '<your Salesforce server URL (e.g. https://na1.salesforce.com) is here>',
  accessToken : '<your Salesforrce OAuth2 access token is here>',
  refreshToken : '<your Salesforce OAuth2 refresh token is here>'
});
conn.on("refresh", function(accessToken, res) {
  // Refresh event will be fired when renewed access token
  // to store it in your storage for next request
});

But this is giving me this error:

Error: Refresh token is specified without oauth2 client information or refresh function

I checked the source code and from that I can say I need some delegateRefreshFunction but I'm not sure what it is.

So, my question is, how can I refresh the token when it expires?

Thanks!

Most helpful comment

you have to pass the oauth2 parameters to the connection constructor.
https://jsforce.github.io/document/#access-token-with-refresh-token has an example.

var conn = new jsforce.Connection({ oauth2 : { clientId : '<your Salesforce OAuth2 client ID is here>', clientSecret : '<your Salesforce OAuth2 client secret is here>', redirectUri : '<your Salesforce OAuth2 redirect URI is here>' }, instanceUrl : '<your Salesforce server URL (e.g. https://na1.salesforce.com) is here>', accessToken : '<your Salesforrce OAuth2 access token is here>', refreshToken : '<your Salesforce OAuth2 refresh token is here>' });

All 4 comments

you have to pass the oauth2 parameters to the connection constructor.
https://jsforce.github.io/document/#access-token-with-refresh-token has an example.

var conn = new jsforce.Connection({ oauth2 : { clientId : '<your Salesforce OAuth2 client ID is here>', clientSecret : '<your Salesforce OAuth2 client secret is here>', redirectUri : '<your Salesforce OAuth2 redirect URI is here>' }, instanceUrl : '<your Salesforce server URL (e.g. https://na1.salesforce.com) is here>', accessToken : '<your Salesforrce OAuth2 access token is here>', refreshToken : '<your Salesforce OAuth2 refresh token is here>' });

I ran into this too, and this worked, thanks for the answer @siddharatha

Yes, this works @siddharatha :+1:

I seem to be getting inconsistent results with this...sometimes my subsequent requests (i.e., conn.describeGlobal) return undefined for no reason (no error in the callback, just fails silently) after calling the oauth2.refreshToken function. So my code looks like something like this:

return new Promise((resolve) => {
   // Before each request, I call the refreshToken function to make sure the accessToken is current
    conn.oauth2.refreshToken(conn.refreshToken, (refreshErr, refreshResult) => {
      if (refreshErr) {
        D.error = refreshErr;
        resolve(D);
      } else {
       D.accessToken = refreshResult.accessToken; // I get the new access token
       D.instanceUrl = refreshResult.instanceUrl;

        // Create a new conn object with the new access token
        const conn2 = new jsforce.Connection({
          oauth2,
          accessToken: D.accessToken,
          instanceUrl: D.instanceUrl,
          refreshToken: conn.refreshToken,
        });

       // Great, now I can use the new conn object to do things, right?
        conn2.describeGlobal((globalErr, globalMeta) => {
          if (globalErr) {
            D.error = globalErr;
            resolve(D);
          } else {
             // Do things with globalMeta, but sometimes it is undefined...
          }
        })
    }
  })
})
  ...

Is there any reason not to create a new conn object with the renewed access token before proceeding with the subsequent salesforce api requests (such as describeGlobal, sobjects, etc.)? I could use the conn.on('refresh') callback, but I can't depend on that callback completing before other important things happen.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fearphage picture fearphage  路  4Comments

CodisRedding picture CodisRedding  路  4Comments

zestyphresh picture zestyphresh  路  7Comments

jbonigomes picture jbonigomes  路  3Comments

jimrae picture jimrae  路  3Comments