Nuxt3自定义useAuth集成@azure/msal-browser遇startPerformanceMeasurement错误
TypeError: this.startPerformanceMeasurement is not a function的问题 问题描述
在Nuxt3中自定义useAuth composable集成@azure/msal-browser时,调用loginRedirect或loginPopup方法触发如下错误:
Uncaught (in promise) TypeError: this.startPerformanceMeasurement is not a function
at PerformanceClient2.startMeasurement (PerformanceClient.ts:100:45)
at BrowserPerformanceClient2.startMeasurement (BrowserPerformanceClient.ts:46:55)
at RedirectClient2.(StandardInteractionClient.ts:204:64)
at step (_tslib.js:87:23)
at Object.next (_tslib.js:68:53)
at _tslib.js:61:71
at new Promise ()
at __awaiter (_tslib.js:57:12)
at StandardInteractionClient2.getDiscoveredAuthority (StandardInteractionClient.ts:202:115)
at RedirectClient2.(StandardInteractionClient.ts:142:48)
问题原因
错误根源是MSAL实例被重复初始化,且Nuxt3 composable中的全局状态管理不当,导致每次调用useAuth()都会重新创建PublicClientApplication实例,MSAL内部性能测量模块因此出现上下文绑定丢失的问题。
解决方案
1. 确保MSAL实例仅初始化一次
修改useAuth composable,仅在首次调用时创建实例,避免重复初始化:
// composables/useAuth.js import * as msal from '@azure/msal-browser' let authService = null export const useAuth = () => { const config = useAppConfig(); // 仅当实例不存在时创建 if (!authService) { authService = new msal.PublicClientApplication(config.msalConfig); } return { signIn } } const signIn = async () => { const tokenRequest = { scopes: ['openid', 'offline_access', 'Users.Read'], } try { await authService.loginRedirect(tokenRequest); } catch (err) { console.error('登录失败:', err); } }
2. 延迟触发登录方法
避免在组件初始化阶段直接调用登录逻辑,改为通过用户交互触发,确保MSAL实例完全初始化:
<script setup> const auth = useAuth() const handleSignIn = () => { auth.signIn() } </script> <template> <button @click="handleSignIn">登录</button> </template>
3. 可选:显式配置MSAL性能测量
若需使用性能测量功能,确保配置中显式启用,保证初始化上下文正确:
// app.config.ts export default defineAppConfig({ msalConfig: { auth: { clientId: '你的客户端ID', authority: 'https://login.microsoftonline.com/你的租户ID', redirectUri: 'http://localhost:3000' }, system: { loggerOptions: { loggerCallback: (level, message, containsPii) => { if (containsPii) return; switch (level) { case msal.LogLevel.Error: console.error(message); return; case msal.LogLevel.Info: console.info(message); return; case msal.LogLevel.Verbose: console.debug(message); return; case msal.LogLevel.Warning: console.warn(message); return; } } }, performance: { enabled: true } } } })
内容的提问来源于stack exchange,提问作者Eric

