Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php HPLeague OAuth2客户端`getAccessToken()`throws";遇到不包含JSON正文的OAuth服务器错误;错误_Php_Oauth 2.0_Slim_Thephpleague_Slim 4 - Fatal编程技术网

Php HPLeague OAuth2客户端`getAccessToken()`throws";遇到不包含JSON正文的OAuth服务器错误;错误

Php HPLeague OAuth2客户端`getAccessToken()`throws";遇到不包含JSON正文的OAuth服务器错误;错误,php,oauth-2.0,slim,thephpleague,slim-4,Php,Oauth 2.0,Slim,Thephpleague,Slim 4,我一直在尝试开发一个API和客户端,它们通过HPLeague的OAuth2和的实现相互通信。在CLI中使用curl命令,我能够生成一个令牌并使用它来访问受保护的资源 用户身份验证依赖于with Slim框架,该框架接受存储在数据库表中的用户名和加密密码。同一个表用于OAuth2实现的用户管理 成功验证用户登录尝试后,将调用的getAccessToken()方法,并从API请求访问令牌。这就是问题所在 我已经使用GenericProvider类测试了功能。我还扩展了提供程序以创建自己的类。使用这两

我一直在尝试开发一个API和客户端,它们通过HPLeague的OAuth2和的实现相互通信。在CLI中使用
curl
命令,我能够生成一个令牌并使用它来访问受保护的资源

用户身份验证依赖于with Slim框架,该框架接受存储在数据库表中的用户名和加密密码。同一个表用于OAuth2实现的用户管理

成功验证用户登录尝试后,将调用的
getAccessToken()
方法,并从API请求访问令牌。这就是问题所在

我已经使用
GenericProvider
类测试了功能。我还扩展了提供程序以创建自己的类。使用这两个提供程序,我在尝试登录时看到以下错误:

Slim Application Error
Type: UnexpectedValueException
Code: 0
Message: An OAuth server error was encountered that did not contain a JSON body
File: /var/www/sloth2-client-php/vendor/league/oauth2-client/src/Provider/AbstractProvider.php
Line: 693

#0 /.../vendor/league/oauth2-client/src/Provider/AbstractProvider.php(626): 
League\OAuth2\Client\Provider\AbstractProvider->parseResponse(Object(GuzzleHttp\Psr7\Response))
#1 /.../src/SlothProvider.php(113): League\OAuth2\Client\Provider\AbstractProvider->getParsedResponse(Object(GuzzleHttp\Psr7\Request))
#2 /.../src/Controller/AuthenticationController.php(69): App\SlothProvider->getAccessToken(Object(League\OAuth2\Client\Grant\ClientCredentials))
#3 /.../vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php(42): App\Controller\AuthenticationController->authenticate(Object(Slim\Psr7\Request), Object(Slim\Psr7\Response), Array)
#4 /.../vendor/slim/slim/Slim/Routing/Route.php(372): Slim\Handlers\Strategies\RequestResponse->__invoke(Array, Object(Slim\Psr7\Request), Object(Slim\Psr7\Response), Array)
#5 /.../vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): Slim\Routing\Route->handle(Object(Slim\Psr7\Request))
#6 /.../vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request))
#7 /.../vendor/slim/slim/Slim/Routing/Route.php(333): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request))
#8 /.../vendor/slim/slim/Slim/Routing/RouteRunner.php(65): Slim\Routing\Route->run(Object(Slim\Psr7\Request))
#9 /.../vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php(58): Slim\Routing\RouteRunner->handle(Object(Slim\Psr7\Request))
#10 /.../vendor/slim/slim/Slim/MiddlewareDispatcher.php(132): Slim\Middleware\RoutingMiddleware->process(Object(Slim\Psr7\Request), Object(Slim\Routing\RouteRunner))
#11 /.../vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php(89): class@anonymous->handle(Object(Slim\Psr7\Request))
#12 /.../vendor/slim/slim/Slim/MiddlewareDispatcher.php(132): Slim\Middleware\ErrorMiddleware->process(Object(Slim\Psr7\Request), Object(class@anonymous))
#13 /.../vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): class@anonymous->handle(Object(Slim\Psr7\Request))
#14 /.../vendor/slim/slim/Slim/App.php(206): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request))
#15 /.../vendor/slim/slim/Slim/App.php(190): Slim\App->handle(Object(Slim\Psr7\Request))
#16 /.../public/index.php(8): Slim\App->run()
#17 {main}

堆栈跟踪中提到的
SlothProvider
类如下所示:

<?php

namespace App;

use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
use Psr\Http\Message\ResponseInterface;
use UnexpectedValueException;

class SlothProvider extends AbstractProvider
{
  use BearerAuthorizationTrait;

  public function __construct()
  {
    $this->clientId = getenv('OAUTH2_CLIENT_ID');
    $this->clientSecret = getenv('OAUTH2_CLIENT_SECRET');
    $this->redirectUri = getenv('OAUTH2_REDIRECT_URI');
  }

  /**
   * Get authorization url to begin OAuth flow
   *
   * @return string
   */
  public function getBaseAuthorizationUrl()
  {
    return getenv('OAUTH2_AUTHORIZATION_URL');
  }

  /**
   * Get access token url to retrieve token
   *
   * @param  array $params
   *
   * @return string
   */
  public function getBaseAccessTokenUrl(array $params)
  {
    return getenv('OAUTH2_ACCESS_TOKEN_URL');
  }

  /**
   * Get provider url to fetch user details
   *
   * @param  AccessToken $token
   *
   * @return string
   */
  public function getResourceOwnerDetailsUrl(AccessToken $token)
  {
    // You don't have one. You might consider throwing an exception here so
    // that, when this is called, you get an error and can code your
    // application to ensure that nothing calls this.
    //
    // Note that $this->getResourceOwner() is the most likely culprit for
    // calling this. Just don't call getResourceOwner() in your code.
  }

  /**
   * Get the default scopes used by this provider.
   *
   * This should not be a complete list of all scopes, but the minimum
   * required for the provider user interface!
   *
   * @return array
   */
  protected function getDefaultScopes()
  {
    return ['basic'];
  }

  /**
   * Check a provider response for errors.
   *
   * @throws IdentityProviderException
   * @param  ResponseInterface $response
   * @param  array $data Parsed response data
   * @return void
   */
  protected function checkResponse(ResponseInterface $response, $data)
  {
    // Write code here that checks the response for errors and throws
    // an exception if you find any.
  }

  /**
   * Generate a user object from a successful user details request.
   *
   * @param array $response
   * @param AccessToken $token
   * @return \League\OAuth2\Client\Provider\ResourceOwnerInterface
   */
  protected function createResourceOwner(array $response, AccessToken $token)
  {
    // Leave empty. You can't use this, since you don't have a clear
    // resource owner details URL. You might consider throwing an
    // exception from here, as well. See note on
    // getResourceOwnerDetailsUrl() above.
  }

  /**
   * Requests an access token using a specified grant and option set.
   *
   * @param  mixed $grant
   * @param  array $options
   * @throws IdentityProviderException
   * @return AccessTokenInterface
   */
  public function getAccessToken($grant, array $options = [])
  {
    $grant = $this->verifyGrant($grant);
    $params = [
      'client_id'     => $this->clientId,
      'client_secret' => $this->clientSecret,
      'redirect_uri'  => $this->redirectUri,
    ];
    $params   = $grant->prepareRequestParameters($params, $options);
    $request  = $this->getAccessTokenRequest($params);
    $response = $this->getParsedResponse($request);
    if (false === is_array($response)) {
      throw new UnexpectedValueException(
        'Invalid response received from Authorization Server. Expected JSON.'
      );
    }
    $prepared = $this->prepareAccessTokenResponse($response);
    $token    = $this->createAccessToken($prepared, $grant);
    return $token;
  }
}


服务器响应一个500状态码,其主体不能被
json\u decode()
解码。来自
json\u last\u error\u msg()
的实际解码消息可以在
UnexpectedValueException
的上一个异常的“getMessage()中找到

要了解它是什么,请尝试从
$response=$this->getParsedResponse($request)捕获异常然后引发上一个异常。e、 g

    try {
        $response = $this->getParsedResponse($request);
    } catch (UnexpectedValueException $e) {
        if ($e->getPrevious()) {
            // json_decode() error message is in $e->getPrevious()->getMessage().
            // An easy way to see it is to throw the previous exception:
            throw $e->getPrevious();
        }
    }

希望错误消息能给你一个错误的线索。否则,您需要查看发送/接收的请求和响应对象。您需要检查
League\OAuth2\Client\Provider\AbstractProvider
中的
getParsedResponse()
方法才能执行此操作。

此处的
SlothProvider
与堆栈跟踪不匹配。至少,我希望第113行是
$response=$this->getParsedResponse($request),但这是第121行…在我的例子中,我得到了$request的空字符串和相同的错误消息(顺便说一句,我尝试了Laravel 6)顺便说一句,我尝试了Laravel 6和5.4,微软的示例使用了Laravel 5.4,但没有使用Laravel 6