Do you know the feeling when your application connected to Salesforce suddenly stop working and you don’t know why?
When this happens?
This kind of issue can happen when integrating with Salesforce using OAuth2 as the authorization method. At some point our access/refresh token pair gets revoked even when our connected app is configured to never expire the refresh token unless manually revoked.
The integration stops working as it is not able to communicate with Salesforce REST API anymore and can’t recover from this state as both tokens are revoked and the app is not able to refresh the access token anymore.
What’s the reason?
The reason is simple – there were too many access tokens issued for the same Salesforce user and connected app. Salesforce limits the number of active sessions for one connected app to 5, one is the web session and the other 4 are OAuth2 sessions. In another words one user can only have 4 active access/refresh token pairs. Once the user requests the 5th access/refresh token pair the oldest one gets revoked. This is not obvious behavior and unfortunately Salesforce OAuth2 documentation does not mention it.
How this usually happen?
Let’s imagine you have a running integration configured using the OAuth2 access token stored in DB for the Salesforce REST API calls. All the configuration including DB changes are done in one database transaction. In case the user doesn’t exist, new one will be added otherwise only the tokens are overridden in DB. Once the access token expires the refresh token procedure is triggered, the DB is updated with new token pair (access and refresh) and the integration start using the new access token. So far all is good.
Now, the user decides to configure another integration with the same Salesforce account, he will proceed with OAuth2 and gets another token pair (2nd). After that the configuration process fails, the reasons can vary – incorrect configuration, network issues etc. As the whole processing takes place in one DB transaction the failure of the configuration process rollbacks all the DB changes including token pair update. It means the new 2nd token pair has been issued by Salesforce OAuth2, but it isn’t stored in DB.
I’m sure you know what happens next… Most of the users will keep trying it again and again. It means the user is requesting new token pairs with each retry, but this new token pair isn’t stored in DB. After 3rd retry the number of issued token pair is 5 causing the oldest token pair gets revoked – the oldest token pair is the one in the DB.
And that’s it! The tokens in DB have been revoked and the first integration relying on them starts failing.
How to avoid this?
The simplest solution is to update the tokens in DB in the separate transaction each time new Salesforce token is issued/received, no matter if the integration configuration process fails or not.
How do I know number of active tokens issued?
Number of active sessions (access/refresh tokens issued) can be found under Setup -> Manage Apps -> Connected Apps OAuth Usage: