3

我目前使用PHP-EWS项目来帮助自动记录来自多个邮箱的电子邮件。该系统运行良好,直到最近我开始遇到"The request failed with HTTP status 401: Unauthorized."错误。

联系微软后,他们说可能是身份验证需要使用令牌而不是用户名/密码。我遇到了 user3434790 提出的这个问题,这似乎正是我正在寻找的,除了我不确定如何首先获取令牌!我看到了一些关于 Javascript 方法的信息,但我的脚本完全是服务器端(PHP),我特别想连接到 Office 365 帐户。

4

1 回答 1

2

好的,到目前为止做一些研究,这基本上是一个分为三个部分的故事。

第一部分是关于获得“授权码”。基本上,这意味着您向 Azure 或 Outlook 365 Dev 注册您的应用程序,然后有一个页面或检查您是否为您的用户提供有效的“令牌”。如果你不这样做,那么你需要得到那个令牌。

基本上,这意味着将您的用户发送到 Microsoft 域上的登录页面,并在 URL 中使用您的 ClientID 和回调 URI(您之前注册的)以及您想要的权限。然后,用户将使用 URL 中所需的“授权码”登录并被引导回您的站点。这是有关如何执行此操作的通用指南。它不处理特定的语言,而是处理请求的一般流程。

一个非常简单且不用于生产的示例是

索引.php

if (!$_SESSION['code']) {
    $redirect = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' .
        '?response_type=code' .
        '&client_id=' . urlencode('clientId') .
        '&redirect_uri=' . urlencode('https://localhost/callback.php') .
        '&scope=' . urlencode('https://outlook.office365.com/Mail.Read')
        ;
    header("Location: {$redirect}");
    exit();
}

回调.php

if (isset($_GET['code'])) {
    $_SESSION['code'] = $_GET['code'];
    header("Location: index.php");
}

第二部分:获取授权令牌

不幸的是,代码并不是您所需要的。这是一个快速的一次性代码,用于获取授权请求所需的实际令牌。您可以通过使用以下数据发布到“ https://login.microsoftonline.com/common/oauth2/v2.0/token ”来做到这一点

  • 客户编号
  • 客户秘密
  • 授权码
  • 重定向 URI
  • 资助类型

使用 Guzzle,可以这样做

$postOptions = array(
    'http_errors' => false,
    'form_params' => array(
        'client_id' => $clientId,
        'client_secret' => $clientSecret,
        'code' => $authorizationCode,
        'redirect_uri' => $redirectUri,
        'grant_type' => 'authorization_code'
    )
);

$url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';

$client = new Client();
$response = $client->request('POST', $url, $postOptions);
$response = $response->getBody()->__toString();

$response = json_decode($response);
return $response->access_token;

一旦你有了你的令牌,你就想保留它。虽然代码是一次性的,但令牌会持续更长时间。从我所见,它似乎在一小时后到期。因此,您想获得一次令牌,然后将其存储在您的会话中,或者您想存储它。获得令牌后,您可以拨打电话。嗯,差不多。

第三部分:肥皂电话

不幸的是,您使用的库根本不支持这一点。它具有作为基本 HTTP 身份验证或 NTLM 的硬编码授权。您可以看到这里没有通过令牌支持的选项。如果你分叉它,你可以删除第 78 和 79 行并更改 ExchangeWebServices 以传递令牌,你只需要添加

'Authorization: Bearer ' . $token

到标题,这应该有效。或者,如果你有时间,你可以尝试使用我编写和维护的那个库的更新版本,garethp/php-ews。虽然它无法为您处理第 1 步,但一旦您获得授权码,它将使第 2 步和第 3 步变得更加容易。这里是一个小例子。不过,这是我今天刚刚加入的新功能,目前仍处于试验阶段。我遇到了权限问题,因为您似乎需要向 Azure AD for Office 365 注册您的应用以获得 EWS 的正确权限,而不是向 Outlook 注册以获得 Outlook REST API 的权限,我可以为 Azure 创建开发帐户有些麻烦。所以我设法创建了一个令牌,使用它进行授权,确保它被传递,只是被告知我拥有的令牌没有权限做需要做的事情。

于 2015-11-20T15:06:47.443 回答