仅当未通过 @azure/msal-react 进行身份验证时才重定向 onLoad

时间:2021-03-19 19:20:01

标签: reactjs azure-active-directory msal

我正在尝试根据我的需要调整 sample project

我的需求基本上是:

  1. 如果用户在导航到根路由时未通过身份验证,则自动重定向登录...
  2. 如果是,则加载受保护的子组件。

我有第 1 步。按预期工作。但是,在他们登录后,它似乎正在尝试再次重新路由,我得到:

<块引用>

interaction_in_progress:交互正在进行中。请确保在调用交互式 API 之前已完成此交互。更多访问:aka.ms/msaljs/browser-errors

  70 | 
  71 | useEffect(() => {
  72 |   if (!isAuthenticated) {
> 73 |     msalInstance.loginRedirect(loginRequest);
     | ^  74 |   }
  75 | })
  76 | 

无论是否存在 !isAuthenticated 条件,它都会这样做。

useIsAuthenticated 的用法来自 this documentation,即使用户已经登录,它似乎也计算为 false

这是我目前所拥有的:

import { Configuration, RedirectRequest } from '@azure/msal-browser';

// Config object to be passed to Msal on creation
export const msalConfig: Configuration = {
  auth: {
    clientId: '<client_id>',
    authority: 'https://login.microsoftonline.com/<tenant_id>',
  },
};

// Add here scopes for id token to be used at MS Identity Platform endpoints.
export const loginRequest: RedirectRequest = {
  scopes: ['User.Read'],
};

// Add here the endpoints for MS Graph API services you would like to use.
export const graphConfig = {
  graphMeEndpoint: 'https://graph.microsoft.com/v1.0/me',
};

// index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import { PublicClientApplication } from '@azure/msal-browser';
import { msalConfig } from './components/authConfig';
import { MsalProvider } from '@azure/msal-react';

const msalInstance = new PublicClientApplication(msalConfig);

ReactDOM.render(
  <React.StrictMode>
    <MsalProvider instance={msalInstance}>
      <App />
    </MsalProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
// App.tsx
import React, { useEffect } from 'react';
import {
  AuthenticatedTemplate,
  UnauthenticatedTemplate,
  useMsal,
  useIsAuthenticated,
} from '@azure/msal-react';
import { loginRequest } from './authConfig';

const App = () => {
  const isAuthenticated = useIsAuthenticated();
  const { instance } = useMsal();

  console.log(isAuthenticated);

  useEffect(() => {
    if (!isAuthenticated) {
      instance.loginRedirect(loginRequest);
    }
  });

  return (
    <div className='App'>
      <AuthenticatedTemplate>
        <div>Signed in...</div>
      </AuthenticatedTemplate>

      <UnauthenticatedTemplate>
        <div>Signing in...</div>
      </UnauthenticatedTemplate>
    </div>
  );
};

export default App;

有关如何解决此问题的建议?

2 个答案:

答案 0 :(得分:2)

好的,我在一些帮助下解决了这个问题:

const App = () => {
  const isAuthenticated = useIsAuthenticated();
  const { instance, inProgress } = useMsal();

  if (inProgress === InteractionStatus.None && !isAuthenticated) {
    instance.loginRedirect(loginRequest);
  }

  return (
    <div className='App'>
      <AuthenticatedTemplate>
        <div>Signed in...</div>
      </AuthenticatedTemplate>

      <UnauthenticatedTemplate>
        <div>Signing in...</div>
      </UnauthenticatedTemplate>
    </div>
  );
};

export default App;

答案 1 :(得分:0)

根据@cjones 解决方案,我尝试了几种方法来稍微调整解决方案以获得更适合我的版本并在此处发布相同的版本。如果有人遇到同样的问题,这会有所帮助。

他的解决方案有两个问题。

  1. LoginRedirect 被调用了两次。
  2. 如果您在身份验证成功后要进行任何 API 调用,那么这将首先被取消,因为第二次调用 LoginRedirect。它在第二次 LoginRedirect 调用后执行(虽然,第二次登录尝试不会要求提供凭据,但它会刷新页面。

我试图用以下方法解决这个问题。

const App = () => {
    const isAuthenticated = useIsAuthenticated();   
    const { inProgress, instance, accounts } = useMsal();

    if (inProgress === InteractionStatus.None && !isAuthenticated) {
        setTimeout(() => {
            if (accounts.length === 0) {
                instance.loginRedirect();
            }
        }, 500)
    }
 
 /** Rest of the code here **/

}
相关问题