You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DevExtreme自定义存储调用API时MSAL获取的AccessToken/IdToken无效如何解决

问题根因说明
  • IdToken 不能用于API认证:IdToken的受众(aud声明)是前端客户端ID,不是后端API的标识,后端校验时匹配失败直接返回401属于正常逻辑,请勿使用IdToken调用业务接口。
  • 直接取loginPopup返回的AccessToken scope不匹配:你在MSAL拦截器中配置了请求https://localhost:44379/api/*时需要的scope为api://cb343c76-cd5b-4af6-8229-014b2522adab/access_as_user,但调用loginPopup时没有显式指定该自定义API的scope,返回的AccessToken默认是应用注册时默认配置的scope(通常是MS Graph相关权限),该Token的aud、scope都不符合后端API校验要求,所以会报签名无效错误。
  • MSAL拦截器正常工作的逻辑是:它会自动匹配请求地址对应的资源配置,主动请求对应scope的有效令牌,和你直接取登录返回的通用令牌逻辑完全不同。
解决步骤

1. 显式获取对应API的有效AccessToken

不要直接使用loginPopup返回的AccessToken,需要调用MSAL的令牌获取接口指定后端API的scope来获取合规令牌,代码示例:

// 定义你后端API对应的令牌请求参数
const apiTokenRequest = {
  scopes: ['api://cb343c76-cd5b-4af6-8229-014b2522adab/access_as_user']
};

// 优先静默获取令牌(用户已登录的情况下无需重复弹窗)
this.authService.acquireTokenSilent(apiTokenRequest)
  .subscribe((res: AuthenticationResult) => {
    // 此处获取的accessToken才是符合后端API要求的有效令牌
    const validApiToken = res.accessToken;
    // 将令牌放到DevExtreme自定义存储的请求头中即可
  }, (err) => {
    // 静默获取失败(如用户登录态过期)时走弹窗重新授权
    if (err instanceof InteractionRequiredAuthError) {
      this.authService.acquireTokenPopup(apiTokenRequest)
        .subscribe((res: AuthenticationResult) => {
          const validApiToken = res.accessToken;
          // 处理令牌逻辑
        })
    }
  });

2. DevExtreme自定义存储适配令牌逻辑

建议在自定义存储的load函数中每次请求前都先获取最新的有效令牌,避免令牌过期导致的认证失败,示例:

const customPagingStore = new CustomStore({
  key: 'id',
  load: async (loadOptions) => {
    // 每次加载分页数据前先获取有效令牌
    const apiTokenRequest = {
      scopes: ['api://cb343c76-cd5b-4af6-8229-014b2522adab/access_as_user']
    };
    const tokenRes = await firstValueFrom(this.authService.acquireTokenSilent(apiTokenRequest));
    // 发起请求携带认证头
    const apiRes = await fetch('https://localhost:44379/api/approveMilestones', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${tokenRes.accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(loadOptions)
    });
    const result = await apiRes.json();
    return {
      data: result.items,
      totalCount: result.total
    };
  }
});

3. 后端配置校验(可选)

如果修改后仍然报错,检查后端JWT校验配置:

  • 受众(aud)配置是否为api://cb343c76-cd5b-4af6-8229-014b2522adab或后端API的客户端ID
  • 签发方(iss)配置是否和Azure AD租户的签发地址一致
  • 权限校验规则是否包含access_as_user scope

内容的提问来源于stack exchange,提问作者Amir Sohail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:24:03