简体   繁体   中英

How can I retrieve a token from msal-react on initial callback?

I'm using msal-react to try and authenticate a user on my app, however the initial redirect back to my app doesn't seem to provide a token. If I refresh the page after the callback the app works as expected. I have Azure AD setup correctly and I have verified that I can get a token with the same user in Postman.

At the moment my index.tsx page looks like this:

import { Configuration, PublicClientApplication } from "@azure/msal-browser";
import { MsalProvider } from "@azure/msal-react";

...

const configuration: Configuration = {
  auth: {
    authority: 'https://login.microsoftonline.com/organizations',
    clientId: '<AppClientId>',
    redirectUri: 'https://localhost:3000',
  }
};
const pca = new PublicClientApplication(configuration);

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <MsalProvider instance={pca}>
        <App />
      </MsalProvider>      
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

Since I want to do an auto login rather than having the user click a login button I am trying to do login from the App.tsx file. This works in that when the app is initially loaded I am redirected to the Azure login page and I can successfully login with my username and password. But when the redirect occurs it hits the same instance.loginRedirect call again due to the fact that accounts is still empty. As said though when I refresh the page in the browser accounts is populated and I am shown the app as expected.

Here is what I have for App.tsx:

function Login(): React.ReactElement {
  const { instance } = useMsal();

  useEffect(() => {
    const accounts = instance.getAllAccounts();    
    if (!accounts || accounts.length < 1) {
      instance.loginRedirect({
        scopes: ["profile", "openid"]
      });
    }
  }, [instance]);

  return (
    <p>Signing in...</p>
  );
}

function App(): React.ReactElement {
  return (
    <>
      <AuthenticatedTemplate>
        <Router>
          <ThemeProvider theme={theme}>
            ... App Components ...
          </ThemeProvider>
        </Router>
      </AuthenticatedTemplate>

      <UnauthenticatedTemplate>
        <Login />
      </UnauthenticatedTemplate>
    </>
  );
}

When I looked into the store I can see that I have a valid access token, so I must be missing a step

I've also tried using the inProgress string to see if I can detect different states to stop the second call from occurring but this hasn't worked either. Everything appears to be working apart from the fact that I cannot stop my app from calling loginRedirect a second time.

Any help on this would be appreciated.

EDIT: Should have mentioned that the error that I get is "interaction_in_progress: Interaction is currently in progress. Please ensure that this interaction has been completed before calling an interactive API."

Try this.

import { InteractionStatus } from "@azure/msal-browser";    
... 

const { instance, inProgress } = useMsal();    
useEffect(() => {
    if (inProgress === InteractionStatus.None && !isAuthenticated) {
        instance.loginRedirect(loginRequest)
            .catch(e => {
                console.error(e);
            });
    }
});

You need to check the InteractionStatus before calling login redirect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM