通知端点验证不适用于 Laravel Endpoint

Jak*_*keD 6 php laravel laravel-5 microsoft-graph-api

我正在使用 Microsoft Graph,需要设置一个 Webhook 来接收电子邮件和日历事件的更改。我能够让它与我的 PHP Laravel 应用程序一起工作,但现在我正在尝试订阅通知,我在验证notificationUrl指向我的公共服务器的 时遇到了问题。

用于创建 Webhook 的脚本返回以下错误:

Client error: POST https://graph.microsoft.com/v1.0/subscriptions resulted in a 400 Bad Request response: 
{ 
  "error": { 
     "code": "InvalidRequest", 
     "message": "Subscription validation request failed. Response must ex (truncated...)
Run Code Online (Sandbox Code Playgroud)

我相信被截断的部分是

订阅验证请求失败。必须对此请求响应 200 OK。

这是我创建订阅的代码:

$data = [
    "changeType" => "created",
    "notificationUrl" => "https://anatbanielmethod.successengine.net/office365/webhooks/events",
    "resource" => "me/events",
    "expirationDateTime" => "2018-12-20T18:23:45.9356913Z",
    "clientState" => "secret",
];

$result = $graph->createRequest('POST', '/subscriptions')
    ->attachBody($data)
    ->execute();
Run Code Online (Sandbox Code Playgroud)

这是我的方法notificationUrl

public function events()
{
    //if validationToken exists return that to validate notificationUrl
    if(isset($_REQUEST['validationToken'])){
        return response($_REQUEST['validationToken'], 200)
            ->header('Content-Type', 'text/plain');
    }

    //process event normally for those that have already been validated
}
Run Code Online (Sandbox Code Playgroud)

这个 URL 再次是公开且实时的,我已经通过使用 Postman 向其发送测试帖子对其进行了测试,并且工作正常。另外,我将此路由添加到我的VerifyCsrfToken中间件中,以允许第三方帖子访问此 URL。

最初,我设置了一个简单的单页 PHP 脚本来测试验证,notificationUrl并且该简单的脚本运行良好。它成功验证了创建的指向它的 Webhook。这是一页脚本代码:

<?php
    if(isset($_REQUEST['validationToken'])){
        echo $_REQUEST['validationToken']; // needed only once when subscribing
    } else {
      //process like normal not a validation Token request...
        }
    }
Run Code Online (Sandbox Code Playgroud)

因此,我希望 Laravel 端点能够像简单的一页 PHP 脚本一样工作,并且是在我在 Postman 中测试两个 URL 时,但当 Office365 在创建新的 Webhook 时尝试验证 Laravel 端点时,Laravel 端点不会进行验证。

我已经全面搜索了这方面的帮助,并通读了我可以在 webhooks 上找到的所有 Microsoft 开发人员文档,这些是文档中一些更有用的部分,但我仍然没有找到这个问题的答案:

有这方面的想法吗?

Jak*_*keD -1

谢谢马克!您关于换行符问题的说法是正确的,我仍然不确定换行符来自哪里,Laravel 似乎是如何添加它的。不用说,我通过添加“ob_clean();”找到了解决方案 在返回响应之前。以下是我更新的 notificationUrl 方法:

public function events()
{
    //if validationToken exists return that to validate notificationUrl
    if(isset($_REQUEST['validationToken'])){

      ob_clean();//this line is cleaning out that previously added linefeed

      return response($_REQUEST['validationToken'], 200)
          ->header('Content-Type', 'text/plain');
    }

    //process event normally for those that have already been validated
}
Run Code Online (Sandbox Code Playgroud)