简体   繁体   English

使用 React.js 进行 MSAL 身份验证和授权

[英]MSAL authentication and authrization with React.js

I am fairly new to React and trying to implement Single Sign On Authentication in my React App.我对 React 还很陌生,并试图在我的 React 应用程序中实现单点登录身份验证。

Objectives:目标:

  • Provide a login page where the user can enter their email address提供一个登录页面,用户可以在其中输入他们的电子邮件地址
  • On click of Sign-in user get the SSO popup (based Azure AD) to accept the terms and sign-in单击“登录”后,用户将获得 SSO 弹出窗口(基于 Azure AD)以接受条款并登录
  • Call graph API to retrieve user details (email ID, etc.)调用图 API 来检索用户详细信息(电子邮件 ID 等)
  • Retrieve the sign in token and store in browser cache (localStorage) and use it for subsequent URL accesses (React routes).检索登录令牌并存储在浏览器缓存 (localStorage) 中,并将其用于后续 URL 访问(React 路由)。

I have come across MSAL ( https://github.com/AzureAD/microsoft-authentication-library-for-js ) which seems to be useful for this.我遇到了 MSAL( https://github.com/AzureAD/microsoft-authentication-library-for-js ),这似乎对此很有用。

What I have tried:我尝试过的:

ReactDOM.render(<MuiThemeProvider theme={theme}> <Router> <Switch> <Route path="/" exact component={Projects}/> <Route path="/projects" exact component={Projects}/> <Route path="/admin" exact component={Admin}/> <Route path="/projectstages/:projectNumber" exact component={ProjectStages}/> <Route path="/formspage" exact component={FormsPage}/> <Route path="/users" exact component={UserManagement}/> </Switch> </Router> </MuiThemeProvider>, document.getElementById('root'));

  • These routes (components) gets rendered within the main App.jsx component:这些路由(组件)在主App.jsx组件中呈现:

class App extends Component { render(){ return( <div className="App"> {this.props.children} </div> ); } }

How do I integrate this within my React app so that only authenticated users can access the React routes along with the objectives I mentioned above?我如何将它集成到我的 React 应用程序中,以便只有经过身份验证的用户才能访问 React 路由以及我上面提到的目标? Please let me know if I can provide more details or explain more about this.如果我可以提供更多详细信息或对此进行更多解释,请告诉我。

This is usually achieved using higher-order-components.这通常是使用高阶组件来实现的。

The idea is, when you load a page that requires authentication, you call an api to get authentication using access token stored from your cookies or whatever storage you use.这个想法是,当你加载一个需要身份验证的页面时,你调用一个 api 来使用从你的 cookie 或你使用的任何存储中存储的访问令牌来获取身份验证。 Then you need to wrap your protected routes to a HOC that checks the authentication data.然后,您需要将受保护的路由包装到检查身份验证数据的 HOC。

import React, {useState, useContext, useRef, createContext } from 'react'

const AuthContext = createContext(null)

export const withAuth = (requireAuth = true) => (WrappedComponent) => {
  function Auth(props) {
    const isMounted = useRef(false);
    // this is the authentication data i passed from parent component
    // im just using 
    const { loading, error, auth } = useContext(AuthContext);
    useEffect(() => {
      isMounted.current = true;
    }, []);
    if (!isMounted.current && loading && requireAuth !== 'optional') {
      return (<span>Loading...</span>);
    }
    if ((!auth || error) && requireAuth === true) {
      return (<Redirect to="/login" />);
    } if (auth && requireAuth === false) {
      return (<Redirect to="/" />);
    }
    return (
      <WrappedComponent {...props} />
    );
  }
  return Auth;
};

export function AuthenticationProvider(props) {
   const [auth, setAuth] = useState()
   const [error, setErr] = usetState()
   const [loading, setLoading] = useState(true)
   useEffect(() => {
     // get authentication here
     api.call('/auth')
       .then(data => {
         setAuth(data)
         setLoading(false) 
       })
      .catch(err => {
        setLoading(false)
        setErr(err)
      })

   })

  return (
    <AuthContext.Provider value={{ auth, error, loading }}>
       {children}
    </AuthContext.Provider>
  )
}

Then you can wrap your App with the Authentication Provider然后您可以使用身份验证提供程序包装您的应用程序

  <AuthenticationProvider>
     <App/>
  </AuthenticationProvider>

And for each of the pages, you use the HOC like this对于每个页面,您都像这样使用 HOC

function ProtectedPage(props){
  // your code here
}

export default withAuth(true)(ProtectedPage)

I'd like to recommend to use package for this: https://www.npmjs.com/package/react-microsoft-login我想建议为此使用包: https : //www.npmjs.com/package/react-microsoft-login

  1. Install:安装:
yarn add react-microsoft-login
# or
npm i react-microsoft-login
  1. Import and configure component:导入和配置组件:
import React from "react";
import MicrosoftLogin from "react-microsoft-login";

export default props => {
  const authHandler = (err, data) => {
    console.log(err, data);
  };

  return (
    <MicrosoftLogin clientId={YOUR_CLIENT_ID} authCallback={authHandler} />
  );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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