Search code examples
pythonreactjsoauth-2.0azure-ad-msal

Using MSAL to acquire refresh token using access_token


I have a app that has a Frontend that uses javascript and a backend that uses python. I want to have a user allow my app permissions to read their email inbox.

To do so, the JS FE has a Sign In button that requests "Mail.Read" permissions and gets an accessToken. I want to store that accessToken in my backend, and when the time is needed i want to refresh the token and access the email again (I have a task in my backend that reads the subjects of emails and displays to the user if certain conditions are met).

How can I accomplish this?

Javascript FE Side:

const msalInstance = new PublicClientApplication(msalConfig);

const loginPopup = async () => {
  try {
    const loginResponse = await msalInstance.loginPopup(
      msalConfig.tokenRequest
    );
    props.onSuccess(loginResponse); // This sends the response to the server
    console.log("loginResponse", loginResponse);
  } catch (err) {
    console.error(err);
    props.onFailure(err);
  }
};

Python BE:

authorization_data = j["data"]
try:
    f = open(consts.O365_OAUTH_CREDS_PATH)
    creds_data = json.load(f)
    f.close()
except:
    raise FileNotFoundError(
        "Could not open file. Make sure that it exists."
    )

app = ConfidentialClientApplication(
    client_id=creds_data["auth"]["client_id"],
    client_credential=creds_data["auth"]["client_secret"],
    authority=f'{creds_data["auth"]["authority_base_uri"]}{authorization_data["tenantId"]}',
)

Solution

  • I was eventually able to solve this using an On-Behalf-Of flow.

    The FE app creates a token that is passed to the BE, that creates a new token to the relevant endpoint.

    The BE creates the new token, and the refresh token, and stores that in the DB. Every time the token needs to be refreshed we use the BE token.