我正在尝试使用带有 React 的 MSAL 登录。 我编写了用于恢复 MSAL 生成的令牌的代码(以便稍后将其与 fetch 方法一起使用);在此过程中,我使用方法 loginPopup() 打开一个弹出窗口,用户必须在其中输入来自 Microsoft 的访问帐户数据,当最终确定时,此弹出窗口必须自动关闭,但事实并非如此;弹出窗口保留并重定向到我的默认页面内:
我不知道这是一个错误还是我需要其他配置; MSAL 的版本是: “@azure/msal-browser”:“^3.1.0”。
我的配置类型是:
const MsalConfig = {
auth: {
clientId: "THIS_IS_SECRET",
authority: "https://login.microsoftonline.com/THIS_IS_SECRET",
redirectUri: "https://myappservicetests.azurewebsites.net/", // Cambia esto a tu URI de redirección
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: false,
},
system: {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case LogLevel.Error:
console.error(message);
return;
case LogLevel.Warning:
console.warn(message);
return;
}
}
}
}
};
我的获取令牌代码是:
const GetLoginToken = async () => {
const msalInstance = new PublicClientApplication(ClientSettings.MsalConfig);
await msalInstance.initialize();
const loginRequest = {
scopes: ["user.read"],
};
const accounts = msalInstance.getAllAccounts();
if (accounts.length > 0) {
const accessTokenRequest = {
scopes: ["user.read"],
account: accounts[0],
};
try {
const tokenResponse = await msalInstance.acquireTokenSilent(accessTokenRequest);
localStorage.setItem("tokenAZWebAppTest", tokenResponse.accessToken);
return tokenResponse.accessToken;
} catch (error) {
// Handle token acquisition error
console.error("Error during silent token acquisition:", error);
}
} else {
try {
msalInstance.addEventCallback((event) => {
if (event.eventType === EventType.LOGIN_SUCCESS) {
window.close();
}
});
const response = await msalInstance.loginPopup(loginRequest);
console.log("Login response: ", response);
if (response.account) {
const tokenRequest = {
scopes: ["user.read"],
account: response.account,
};
const tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest);
localStorage.setItem("tokenAZWebAppTest", tokenResponse.accessToken);
return tokenResponse.accessToken;
}
} catch (error) {
console.error("Error during login:", error);
}
}
return null;
}
我不得不使用另一种方法,我发现IE和Safari的方法loginPopup()会产生错误;为此,我直接使用 msal-react 使用唯一实例并使用 Redirect:
我使用 Msal React 示例
的文档在我的index.js中使用MsalProvider:
const pca = new PublicClientApplication(ClientSettings.MsalConfig);
root.render(
<MsalProvider instance={pca}>
<BrowserRouter basename={baseUrl}>
<App />
</BrowserRouter>
</MsalProvider>
);
对于我的页面组件,我使用了库的方法:
export default function Post() {
const { instance, accounts, inProgress } = useMsal();
const account = useAccount(accounts[0] || {});
...
useEffect(() => {
(async function () {
if(account){
await LoadList();
}
})();
}, [account, instance]);
const LoadList = async () => {
let list = await PostService.GetListPosts(instance);
if (list !== null) setPosts(list);
};
return(
<MsalAuthenticationTemplate
interactionType={InteractionType.Redirect}
authenticationRequest={ClientSettings.LoginRequest}
>
<div>...</div>
</MsalAuthenticationTemplate>
);
通过实例,我可以在另一个文件的另一种方法中获取令牌:
const acquireAccessToken = async (msalInstance) => {
const activeAccount = msalInstance.getActiveAccount(); // This will only return a non-null value if you have logic somewhere else that calls the setActiveAccount API
const accounts = msalInstance.getAllAccounts();
if (!activeAccount && accounts.length === 0) {
alert("Users not signed in.")
return null;
}
const request = {
scopes: ["User.Read"],
account: activeAccount || accounts[0]
};
const authResult = await msalInstance.acquireTokenSilent(request);
return authResult.accessToken
}