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

时间:2018-12-19 18:26:20

标签: php laravel laravel-5 microsoft-graph

我正在使用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...)

我认为截断的部分是

  

订阅验证请求失败。必须以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();

这是我的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
}

该URL再次为public and live,我已经通过使用邮递员向其发送测试文章进行了测试,并且工作正常。另外,我将此路由添加到了VerifyCsrfToken中间件中,以允许第三方发布访问此URL。

最初,我设置了一个简单的单页PHP脚本来测试对notificationUrl的验证,并且该简单脚本可以正常工作。它成功验证了创建指向它的Webhooks。这是一页脚本代码:

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

因此,我希望Laravel端点可以像简单的一页PHP脚本一样工作,并且是在邮递员中测试两个URL时,但是当Office365尝试在创建新的Webhook时对其进行验证时,Laravel端点无法进行验证。

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

对此有何想法?

2 个答案:

答案 0 :(得分:0)

谢谢马克!您对于换行是问题是正确的,但我仍然不确定换行来自何处​​,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
}

答案 1 :(得分:0)

奇怪的是,JakeD的答案要求使用ob_clean()。这是我的Laravel 5.7.x应用程序中的webhook控制器方法:

 @ContentChildren(StepComponent) steps: QueryList<StepComponent> = new QueryList<StepComponent>();

我看不到多余的换行符,并且Microsoft Graph API订阅已验证并创建。