When a Salesforce token expires, the `RestClient::apiCall` is never able to refresh it. The code looks like this:

    if (!$this->isInit()) {
      throw new RestException(NULL, $this->t('RestClient is not initialized.'));
    }
    if (!$this->authToken) {
      $this->authToken = $this->authManager->refreshToken();
    }

However, the problem is that if `$this->authToken` isn't set, the `isInit()` function returns FALSE. So the exception for "RestClient is not initialized' is thrown, and it never gets to the lines below to call `refreshToken`.

To make matters worse, the RestClient stores the `authToken` locally and does not expose any method for setting it or refreshing it. Using the Drush command as an example I can see how to refresh the token, but that doesn't actually update the token cached in the RestClient.

Any workaround would be appreciated, but the above logic also needs to be fixed so the apiCall is able to properly refresh tokens when they expire.

(Also note, we are not using the "pull" or "push" submodules, just using the RestClient, so we don't have any cron jobs to keep the API token active, nor do we want that. We want to properly refresh the token whenever it expires)

CommentFileSizeAuthor
#6 3157771-6.patch1.04 KBmpotter

Comments

mpotter created an issue. See original summary.

aaronbauman’s picture

Thanks for the detail.
I think this is related to a bunch of other threads in the issue queue.

For a workaround, have you tried revoking?
There's a tab / local action from the auth provider entity listing.

mpotter’s picture

I need the API to be able to refresh tokens as needed. There can't be any required manual action. I've got a custom service that is calling the Salesforce Client API. If the API isn't used in a while, the next API calls start to fail with no way to detect and resume (since the internal Token cannot be set).

If I manually use the Edit/Re-auth in the UI, then it all starts to work. But this isn't a solution for this client. I'm going to work on a patch. I did a search for tokens and didn't see anything pointing to this specific code issue. Please link if there is already a related patch out there I missed.

aaronbauman’s picture

gotcha.
Have you considered updating to a JWT auth provider?
Might be another way to circumvent the issue.

Alternatively you might try the drush9/10 commands `salesforce:refresh-token` and `salesforce:revoke-token`

mpotter’s picture

I'm already using the JWT auth provider. The drush commands work, but again, that's a manual step. And I tried copying the code from the Drush command into my own init function that I check before calling the RestClient, but there is no way to set the protected authToken variable within the client, so it's still null and still causes the "client not initialized" error.

mpotter’s picture

StatusFileSize
new1.04 KB

Here is a patch that fixes the issue for me. It will always try to refresh an invalid token and should fix anything that uses `isInit` and not just the apiCall function.

aaronbauman’s picture

Version: 8.x-4.1 » 8.x-4.x-dev
Status: Active » Needs review

Thanks, i'll take this for a spin.

bakulahluwalia’s picture

@mpotter, Have you tested the #6 patch for oauth as well? I don't want to switch to jwt so just checking before applying if it works for OAuth as well.

aaronbauman’s picture

Status: Needs review » Reviewed & tested by the community

i think this is ready to go in.

cross-posting #3163385: $provider->refreshAccessToken doesn't keep refresh token which addresses the inability to refresh auth token for interactive oauth.

aaronbauman’s picture

Status: Reviewed & tested by the community » Fixed

committed, thanks again.

  • AaronBauman committed 5199b25 on 8.x-4.x authored by mpotter
    Issue #3157771 by mpotter, AaronBauman: API never refreshes auth token
    

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.