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

Office365 OAuth令牌获取问题:CURL请求返回NULL需排查

问题核心原因

你当前调用的/oauth2/v2.0/authorize端点属于隐式授权/授权码流程,这个流程必须依赖用户手动打开浏览器完成登录交互,后台cron任务没有用户交互环境,所以直接用curl请求只会返回登录页面的HTML内容(而非JSON格式的令牌),json_decode自然会得到NULL。

正确解决方案:使用无用户交互的令牌流程

后台服务获取Office365邮箱访问令牌,应该用客户端凭证流程(应用级权限,无需模拟特定用户)或密码凭证流程(模拟特定用户,不推荐生产环境使用),调用的是/oauth2/v2.0/token端点,而非authorize。

方案1:客户端凭证流程(推荐,应用级权限)

适用于后台服务直接访问邮箱资源(比如读取所有邮箱的邮件,需要在Azure AD中给应用分配对应的应用权限,如Mail.Read)。

修改后的CURL代码:

$tenantId = "你的租户ID";
$clientId = "你的应用ID";
$clientSecret = "你的应用密钥(在Azure AD应用注册中生成)";

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => "https://login.microsoftonline.com/" . $tenantId . "/oauth2/v2.0/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => http_build_query(array(
    'grant_type' => 'client_credentials',
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'scope' => 'https://graph.microsoft.com/.default' // 应用权限的默认范围
  )),
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/x-www-form-urlencoded'
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  $responseDecode = json_decode($response, true);
  var_dump($responseDecode); // 这里会返回包含access_token的JSON
}

方案2:密码凭证流程(模拟特定用户,不推荐)

如果必须模拟某个用户访问其个人邮箱,可以用这个流程,但需要用户的账号密码,且微软不建议生产环境使用(密码泄露风险高,且MFA用户无法使用)。

修改后的CURL代码:

$tenantId = "你的租户ID";
$clientId = "你的应用ID";
$username = "目标用户邮箱(如user@domain.com)";
$password = "用户密码";

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => "https://login.microsoftonline.com/" . $tenantId . "/oauth2/v2.0/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => http_build_query(array(
    'grant_type' => 'password',
    'client_id' => $clientId,
    'username' => $username,
    'password' => $password,
    'scope' => 'https://graph.microsoft.com/User.Read Mail.Read' // 需要的用户权限
  )),
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/x-www-form-urlencoded'
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  $responseDecode = json_decode($response, true);
  var_dump($responseDecode);
}
额外注意事项
  • 客户端凭证流程需要在Azure AD应用注册中添加应用权限(而非委派权限),并完成管理员同意。
  • 密码凭证流程需要添加委派权限,且用户不能开启MFA(否则验证失败)。
  • 建议使用http_build_query来构建POST参数,避免手动拼接出现编码问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:10:27