Vue应用对接Azure时遇uninitialized_public_client_application错误求助
问题:Azure MSAL初始化错误导致无法获取访问令牌
运行代码尝试获取Azure访问令牌时,出现以下错误:
BrowserAuthError: uninitialized_public_client_application: You must call and await the initialize function before attempting to call any other MSAL API.
相关代码如下:
msalConfig.ts
export const msalConfig = { auth: { clientId: import.meta.env.VITE_APP_CLIENT_ID, authority: `https://login.microsoftonline.com/${import.meta.env.VITE_APP_TENANT_ID}`, redirectUri: "https://localhost/spa/sign-in", postLogoutUrl: "https://localhost", }, cache: { cacheLocation: "localStorage", storeAuthStateInCookie: false, }, }; export const loginRequest = { scopes: ["User.Read"], };
initializeMsal.ts
import { PublicClientApplication } from "@azure/msal-browser"; import { msalConfig } from "@/config/msalConfig"; let msalInstance: PublicClientApplication | null = null; export const initializeMsal = async (): Promise<PublicClientApplication> => { if (!msalInstance) { msalInstance = new PublicClientApplication(msalConfig); } return msalInstance; };
main.ts
import { createApp } from 'vue'; import App from './App.vue'; import { initializeMsal } from './msalAuthService'; const initApp = async () => { try { await initializeMsal(); createApp(App).mount('#app'); } catch (error) { console.error('Failed to initialize MSAL', error); } }; initApp();
msalAuthService.ts
import type { AccountInfo, AuthenticationResult } from "@azure/msal-browser"; import { loginRequest } from "@/config/msalConfig"; import { initializeMsal } from "@/config/initializeMsal"; export const login = async (): Promise<AuthenticationResult | null> => { try { const msalInstance = await initializeMsal(); return await msalInstance.loginPopup(loginRequest); } catch (error) { console.error(error); return null; } }; export const logout = async (): Promise<void> => { try { const msalInstance = await initializeMsal(); await msalInstance.logout(); } catch (error) { console.error(error); } }; export const getAccount = async (): Promise<AccountInfo | null> => { const msalInstance = await initializeMsal(); const accounts = msalInstance.getAllAccounts(); return accounts.length > 0 ? accounts[0] : null; }; export const acquireToken = async (): Promise<string | null> => { const msalInstance = await initializeMsal(); try { const account = getAccount(); if (!account) { throw new Error('No signed in account found.'); } const response = await msalInstance.acquireTokenSilent({ ...loginRequest, account, }); return response.accessToken; } catch (error) { console.error(error); return null; } };
解决方案
错误原因
- MSAL实例未完成初始化:创建
PublicClientApplication实例后,必须调用并等待handleRedirectPromise()执行完成,才能确保实例处于可用状态,否则调用其他MSAL API会触发未初始化错误。 - 异步调用未等待:
acquireToken函数中调用getAccount()时未添加await,导致account是Promise对象而非实际的AccountInfo实例,后续传入acquireTokenSilent会引发异常。
代码修复
1. 更新initializeMsal.ts,补充初始化步骤
import { PublicClientApplication } from "@azure/msal-browser"; import { msalConfig } from "@/config/msalConfig"; let msalInstance: PublicClientApplication | null = null; export const initializeMsal = async (): Promise<PublicClientApplication> => { if (!msalInstance) { msalInstance = new PublicClientApplication(msalConfig); // 调用handleRedirectPromise完成实例初始化 await msalInstance.handleRedirectPromise(); } return msalInstance; };
2. 修复msalAuthService.ts中的acquireToken函数
export const acquireToken = async (): Promise<string | null> => { const msalInstance = await initializeMsal(); try { // 添加await等待异步函数返回实际结果 const account = await getAccount(); if (!account) { throw new Error('No signed in account found.'); } const response = await msalInstance.acquireTokenSilent({ ...loginRequest, account, }); return response.accessToken; } catch (error) { console.error(error); return null; } };
完成以上修复后,MSAL实例会在应用启动时完成完整初始化,调用各类API时就不会再触发未初始化错误。
内容的提问来源于stack exchange,提问作者ProMahmudul
相关产品推荐
相关产品推荐

