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

Microsoft Graph On-Behalf-Of令牌是否仅可单次使用?

关于On-Behalf-Of令牌二次调用Graph返回401的问题分析

先给你明确核心结论:On-Behalf-Of(OBO)令牌绝对不是一次性使用的——只要在令牌的有效期内(通常1小时左右),完全可以重复调用Microsoft Graph API。所以你遇到的问题,100%是代码逻辑的问题,和令牌本身无关。

问题根源拆解

你修改后的Promise调用链里,第一个.then((serverSideToken) => { return useServerSideToken(serverSideToken); })执行完后,下一个.then拿到的serverSideToken其实是undefined!

为什么会这样?因为你的useServerSideToken函数在处理完Graph响应后,只调用了display方法,但没有返回任何值(更没有返回传入的令牌)。在Promise链中,每个.then的返回值会自动作为下一个.then的参数,所以当useServerSideToken没有返回令牌时,下一个.then拿到的就是undefined——用undefined作为Bearer令牌去请求Graph,必然会返回401未授权。

哪怕你调换调用顺序,第二次调用依然会拿到undefined的令牌,所以结果还是一样的。

解决方案

只需要修改你的两个Graph调用函数,让它们在处理完响应后返回传入的令牌,这样Promise链就能正确传递令牌了:

修改useServerSideToken函数(假设原函数是调用/me接口):

function useServerSideToken(token) {
  display("3. Call https://graph.microsoft.com/v1.0/me with the server side token");
  return fetch("https://graph.microsoft.com/v1.0/me", {
    method: 'GET',
    headers: {
      "accept": "application/json",
      "authorization": "bearer " + token
    },
    mode: 'cors',
    cache: 'default'
  })
  .then((response) => {
    if (response.ok) {
      return response.json();
    } else {
      throw (`Error ${response.status}: ${response.statusText}`);
    }
  })
  .then((profile) => {
    display(JSON.stringify(profile, undefined, 4), 'pre');
    return token; // 关键:返回令牌,供下一个then使用
  });
}

同样修改useServerSideTokenAgain函数:

function useServerSideTokenAgain(token) {
  display("4. Call https://graph.microsoft.com/v1.0/me/messages with the server side token");
  return fetch("https://graph.microsoft.com/v1.0/me/messages?$select=sender,subject", {
    method: 'GET',
    headers: {
      "accept": "application/json",
      "authorization": "bearer " + token
    },
    mode: 'cors',
    cache: 'default'
  })
  .then((response) => {
    if (response.ok) {
      return response.json();
    } else {
      throw (`Error ${response.status}: ${response.statusText}`);
    }
  })
  .then((profile) => {
    display(JSON.stringify(profile, undefined, 4), 'pre');
    return token; // 同样返回令牌,后续调用也能正常使用
  });
}

修改后,Promise链里的每个.then都能正确接收到有效的令牌,两次Graph调用都会用合法的Bearer令牌请求,就不会再出现401的问题了。

你也可以在第二次调用前加个console.log(serverSideToken)验证一下,修改前应该会打印undefined,修改后会打印有效的令牌字符串,这也能直观确认问题所在。

内容的提问来源于stack exchange,提问作者Hilton Giesenow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:43:15