forcedotcom / SalesforceMobileSDK-ReactNative

BSD 3-Clause "New" or "Revised" License
49 stars 54 forks source link

Access Token Refresh Causes Session Loss and 'No User Account Found' Error in Salesforce Mobile SDK (React Native) #394

Open aanuragb007 opened 4 days ago

aanuragb007 commented 4 days ago

Hi Team,

I'm currently working on a React Native project using the Salesforce Mobile SDK and facing some challenges with access token refresh.

Background:
To avoid session loss, I’ve been refreshing the token manually by calling the /services/oauth2/token endpoint using the stored refresh token and updating the local state with the new access token. However, after refreshing the token this way, the SDK doesn’t seem to recognize the new token, resulting in a lost session and forcing the user to reauthenticate.

Implementation:
I’ve also tried a different approach by implementing a "cheap" request to check the access token's validity. If the token is invalid, I attempt to refresh it. Below is my implementation:

const ensureValidToken = () => {
  return new Promise((resolve, reject) => {
    net.resources(
      (response) => {
        // Token is valid, get credentials
        oauth.getAuthCredentials(
          (credentials) => {
            dispatch(getAuthTokenDetails({
              ...authTokenDetails, 
              accessToken: credentials.accessToken
            }));
            dispatch(authToken(credentials.accessToken));
            resolve(credentials.accessToken);
          },
          reject
        );
      },
      (error) => {
        // Token expired, try refreshing
        const refreshToken = authTokenDetails?.refreshToken;
        const body = `/token?grant_type=refresh_token&client_secret=${ENVIRONMENT.tokenClientSecret}&client_id=${ENVIRONMENT.tokenClientID}&refresh_token=${refreshToken}`;

        net.sendRequest(
          '/services/oauth2',
          body,
          (response) => {
            dispatch(getAuthTokenDetails({
              ...authTokenDetails, 
              accessToken: response.access_token
            }));
            dispatch(authToken(response.access_token));
            resolve(response.access_token);
          },
          reject,
          'POST',
          { 'Content-Type': 'application/x-www-form-urlencoded' }
        );
      }
    );
  });
};

Issue:
While the implementation successfully retrieves the new access token, I encounter an error:
SmartStoreReactBridge.clearSoup failed: "java.lang.Exception: No user account found".

Request:
Is there a recommended way within the Salesforce Mobile SDK to refresh the access token internally so that the SDK recognizes it without disrupting the session? Additionally, could you guide me on resolving the "No user account found" error?

Thank you!

attachment_github_issue

image
wmathurin commented 2 days ago

If you get an error for the net.resources call, it means that you refresh token has expired and can no longer be used to get an access token. So the (error) => { ... } block should also get an error from the server. When your refresh token is no longer valid, we get rid of the user account. And attempts to use it will return the "No user account found". That in itself is not a bug. But you should be taken to the login screen when you don't have a valid user left.

Is your application and iOS or Android application? Did you use forcereact to create your application? What template did you start with?