【问题标题】:PHP oAuth POST requestsPHP oAuth POST 请求
【发布时间】:2016-11-19 02:33:35
【问题描述】:

在获取我的 oAuth POST 请求以返回可行响应时遇到了一些问题。任何想法将不胜感激。

$request = $provider->getAuthenticatedRequest(
    'POST',
    'https://graph.microsoft.com/v1.0/me/calendar/events',
    $_SESSION['access_token'],
    ['body' =>
        json_encode([
            'Id' => null,
            'Subject' => 'Test 54575',
            'Start' => [
                'DateTime' => '2016-11-17T02:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'End' => [
                'DateTime' => '2016-11-17T04:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'Body' => [
                'ContentType' => 'Text',
                'Content' => 'estruyf'
            ],
            'IsReminderOn' => false
        ])
    ]
);

$response = $provider->getResponse($request);

错误:

Fatal error: Uncaught UnexpectedValueException: Failed to parse JSON response: Syntax error in C:\projects\agentprocal\vendor\league\oauth2-client\src\Provider\AbstractProvider.php:663 Stack trace: #0 C:\projects\agentprocal\vendor\league\oauth2-client\src\Provider\AbstractProvider.php(704): League\OAuth2\Client\Provider\AbstractProvider->parseJson(NULL) #1 C:\projects\agentprocal\vendor\league\oauth2-client\src\Provider\AbstractProvider.php(643): League\OAuth2\Client\Provider\AbstractProvider->parseResponse(Object(GuzzleHttp\Psr7\Response)) #2 C:\projects\agentprocal\index.php(58): League\OAuth2\Client\Provider\AbstractProvider->getResponse(Object(GuzzleHttp\Psr7\Request)) #3 {main} thrown in C:\projects\agentprocal\vendor\league\oauth2-client\src\Provider\AbstractProvider.php on line 663

我在创建令牌或请求数据方面没有任何问题。如果有人需要任何进一步的信息,请随时询问。谢谢!

(使用“league/oauth2-client”:“^1.4”)

【问题讨论】:

  • 我想我为您找到了解决方案,您只是不设置标题。请检查我的答案,让我知道它是否有效:) 我很好奇。
  • @KarolGasienica 我已经在你的回答中回复了

标签: php oauth-2.0


【解决方案1】:

最后正确答案

问题

我目前正在查看该课程AbstractProvider,并且您似乎在供应商中拥有:

protected function parseJson($content) {
    $content = json_decode($content, true);
    if (json_last_error() !== JSON_ERROR_NONE) { // ! here that problem occurs
        throw new UnexpectedValueException(sprintf(
            "Failed to parse JSON response: %s",
            json_last_error_msg()
        ));
    }
    return $content;
}

抛出一个异常,说明解析 JSON 存在问题,因为在另一个函数中我们有:

protected function parseResponse(ResponseInterface $response) {
    $content = (string) $response->getBody();
    $type = $this->getContentType($response);

    if (strpos($type, 'urlencoded') !== false) { // ! here he checks header
        parse_str($content, $parsed);
        return $parsed;
    }

    // Attempt to parse the string as JSON regardless of content type,
    // since some providers use non-standard content types. Only throw an
    // exception if the JSON could not be parsed when it was expected to.

    try {
        return $this->parseJson($content);
    } catch (UnexpectedValueException $e) { // ! here it catch
        if (strpos($type, 'json') !== false) { // ! again he checks header
            throw $e; // ! and here it throw
        }
        return $content;
    }
}

解决方案

您似乎没有设置正确的标题。

因此,如果您在请求中添加如下内容:

$options['header']['Content-Type'] = 'application/x-www-form-urlencoded';

它应该可以工作,因为它只会返回一个字符串,而不是在 protected function parseJson($content) 方法中尝试 json_decode()

在您的代码中,它将如下所示:

$request = $provider->getAuthenticatedRequest(
    'POST',
    'https://graph.microsoft.com/v1.0/me/calendar/events',
    $_SESSION['access_token'],
    ['body' =>
        json_encode([
            'Id' => null,
            'Subject' => 'Test 54575',
            'Start' => [
                'DateTime' => '2016-11-17T02:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'End' => [
                'DateTime' => '2016-11-17T04:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'Body' => [
                'ContentType' => 'Text',
                'Content' => 'estruyf'
            ],
            'IsReminderOn' => false
        ]),
     'header' => [
         'Content-Type' => 'application/x-www-form-urlencoded', // set header
         ],
    ],
);

$response = $provider->getResponse($request);

如果您想在 JSON 中获得响应,您应该将标题设置为:

$options['header']['Accept'] = `application/json`;
$options['header']['Content-Type'] = `application/json`;

它会在你的代码中看起来像:

$request = $provider->getAuthenticatedRequest(
    'POST',
    'https://graph.microsoft.com/v1.0/me/calendar/events',
    $_SESSION['access_token'],
    ['body' =>
        json_encode([
            'Id' => null,
            'Subject' => 'Test 54575',
            'Start' => [
                'DateTime' => '2016-11-17T02:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'End' => [
                'DateTime' => '2016-11-17T04:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'Body' => [
                'ContentType' => 'Text',
                'Content' => 'estruyf'
            ],
            'IsReminderOn' => false
        ]),
     'header' => [
         'Content-Type' => 'application/json', // set content type as JSON
         'Accept' => 'application/json', // set what you expect in answer
         ],
    ],
);

$response = $provider->getResponse($request);

更新

在我们的聊天对话之后,我们得到了解决方案。问题出在标题上,正确的代码是:

$body = [
            'Id' => null,
            'Subject' => 'Test 54575',
            'Start' => [
                'DateTime' => '2016-11-17T02:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'End' => [
                'DateTime' => '2016-11-17T04:00:00',
                'TimeZone' => 'W. Europe Standard Time'
            ],
            'IsReminderOn' => false
        ];

$options['body'] = json_encode($body);
$options['headers']['Content-Type'] = 'application/json;charset=UTF-8';

$request = $provider->getAuthenticatedRequest(
    'POST',
    'https://graph.microsoft.com/v1.0/me/calendar/events',
    $_SESSION['access_token'],
    $options
);

$response = $provider->getResponse($request);

【讨论】:

  • 感谢您的帮助。但似乎得到了完全相同的错误。
  • 尝试将两个标题都设置为application/x-www-form-urlencoded,就像 JSON 一样
  • 您也可以在该供应商功能中尝试一些var_dump,以检查它为什么会出现问题。例如var_dump ($content);throw 之前。并写下里面的内容。
  • 切换了标头类型但无济于事,但是在检查了抛出响应后,我收到“写请求(不包括 DELETE)必须包含 Content-Type 标头声明。”
  • 必须有一种方法可以在发送请求之前设置标头。我会尽快检查并回复:)
猜你喜欢
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 2013-05-13
相关资源
最近更新 更多