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

Posted

技术标签:

【中文标题】仅当未使用 @azure/msal-react 进行身份验证时才重定向 onLoad【英文标题】:Redirect onLoad only if not authenticated with @azure/msal-react 【发布时间】:2021-06-17 05:32:09 【问题描述】:

我正在尝试调整 sample project 以满足我的需要。

我的需求本质上是:

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

我有第 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;

关于如何解决这个问题的建议?

【问题讨论】:

【参考方案1】:

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

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;

【讨论】:

这实际上完全适合我,这段代码调用了两次 LoginRedirect 调用。因此,如果我在登录后编写一些 API 调用,在第二次登录后第一次被取消执行【参考方案2】:

您可以简单地使用MsalAuthenticationTemplate component 而不是AuthenticatedTemplate/UnauthenticatedTemplate

import React from "react";
import  MsalAuthenticationTemplate  from "@azure/msal-react";
import  InteractionType  from "@azure/msal-browser";

function ErrorComponent(error) 
    return <p>An Error Occurred: error</p>;


function LoadingComponent() 
    return <p>Authentication in progress...</p>;


export function Example() 
    const authRequest = 
        scopes: ["openid", "profile"]
    ;

    return (
        // authenticationRequest, errorComponent and loadingComponent props are optional
        <MsalAuthenticationTemplate 
            interactionType=InteractionType.Popup 
            errorComponent=ErrorComponent 
            loadingComponent=LoadingComponent
        >
            <p>At least one account is signed in!</p>
        </MsalAuthenticationTemplate>
      )
;

【讨论】:

【参考方案3】:

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

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

    Lo​​ginRedirect 被调用了两次。 如果您在身份验证成功后要进行任何 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 **/


【讨论】:

以上是关于仅当未使用 @azure/msal-react 进行身份验证时才重定向 onLoad的主要内容,如果未能解决你的问题,请参考以下文章

输入类型日期的占位符(仅当未输入值时)

仅当未附加性能分析器时 UI 线程锁定

当未选择下拉菜单时,使用 jquery 获取默认值

当未使用 Environment.Exit() 时,.net 程序可以具都有哪些退出代码?

光标线的颜色在哪里定义?

我收到此错误:当未使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式