我创建了一个基本的 React 应用程序,在其中实现了路由的概念,并使用 Azure AD 进行身份验证。当我尝试使用登录按钮登录时,它工作正常,但我希望当我尝试访问主页时,它会自动重定向到登录页面(Microsoft 登录),而无需单击任何按钮。
这是我的“App.js”代码,在“AuthConfig”中我只是声明了我的 clientId、redirecturi、范围和权限。
import Prices from "./pages/Prices";
import Ticket from "./pages/Ticket";
import Money from "./pages/Money";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import {config} from "./AuthConfig";
import {PublicClientApplication} from '@azure/msal-browser';
import React from "react";
class App extends React.Component<any, any>{
publicClientApplication: PublicClientApplication;
constructor(props){
super(props);
this.state = {
error: null,
isAuthenticated: false,
user:{}
};
this.login=this.login.bind(this)
this.publicClientApplication = new PublicClientApplication({
auth:{
clientId: config.appId,
redirectUri: config.redirectUri,
authority: config.authority
},
cache:{
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false
}
});
}
async login(){
try{
await this.publicClientApplication.loginPopup(
{
scopes: config.scopes,
prompt:"select_account"
});
this.setState({isAuthenticated:true})
}
catch(err){
this.setState({
isAuthenticated:false,
user:{},
error:err
});
}
}
logout(){
this.publicClientApplication.logoutPopup();
}
render() {
return(
<div className="App">
{this.state.isAuthenticated ? <p>
<BrowserRouter>
<Routes>
<Route path="/" element={<Prices />} />
</Routes>
</BrowserRouter>
</p>:
<p>
<button onClick={() => this.login()} > Login </button>
</p>
}
<BrowserRouter>
<Routes>
<Route path="/Money" element={<Money />}></Route>
<Route path="/Ticket" element={<Ticket/>}></Route>
</Routes>
</BrowserRouter>
</div>
);
}
}
export default App;
如果您只是希望在安装
login
组件时而不是单击按钮时自动调用 App
函数,您可以在 componentDidMount
生命周期方法中执行此操作。
示例:
class App extends React.Component<any, any> {
publicClientApplication: PublicClientApplication;
constructor(props) {
super(props);
this.state = {
error: null,
isAuthenticated: false,
user: {}
};
this.publicClientApplication = new PublicClientApplication({
auth: {
clientId: config.appId,
redirectUri: config.redirectUri,
authority: config.authority
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false
}
});
}
componentDidMount() {
this.login();
}
login = sync () => {
try {
await this.publicClientApplication.loginPopup({
scopes: config.scopes,
prompt: "select_account"
});
this.setState({ isAuthenticated: true });
} catch(err) {
this.setState({
isAuthenticated: false,
user: {},
error: err
});
}
}
logout() {
this.publicClientApplication.logoutPopup();
}
render() {
return(
<div className="App">
{this.state.isAuthenticated && (
<BrowserRouter>
<Routes>
<Route path="/" element={<Prices />} />
</Routes>
</BrowserRouter>
)}
<BrowserRouter>
<Routes>
<Route path="/Money" element={<Money />} />
<Route path="/Ticket" element={<Ticket />} />
</Routes>
</BrowserRouter>
</div>
);
}
}
我也不确定使用两个路由器会发生什么,您很可能想要合并这些路由器,以便所有路由都在同一个路由上下文中呈现。
示例:
<div className="App">
<BrowserRouter>
<Routes>
<Route
path="/"
element={this.state.isAuthenticated ? <Prices /> : null}
/>
<Route path="/Money" element={<Money />} />
<Route path="/Ticket" element={<Ticket />} />
</Routes>
</BrowserRouter>
</div>
在 React 组件中使用 componentDidMount 和在功能组件中使用 useEffect 不起作用,因为登录和 acquireToken API 是异步的,因此您需要确保在调用另一个承诺之前已解决结果承诺。此页面很好地解释了它以及如何解决问题:https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/errors.md#interaction_in_progress