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)
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | 3157771-6.patch | 1.04 KB | mpotter |
Comments
Comment #2
aaronbaumanThanks 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.
Comment #3
mpotter commentedI 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.
Comment #4
aaronbaumangotcha.
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`
Comment #5
mpotter commentedI'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.
Comment #6
mpotter commentedHere 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.
Comment #7
aaronbaumanThanks, i'll take this for a spin.
Comment #8
bakulahluwalia@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.
Comment #9
aaronbaumani 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.
Comment #10
aaronbaumancommitted, thanks again.