From e49366c185d1aacd4ffa05494e86df152a054a06 Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Tue, 3 Jan 2017 11:52:13 -0800 Subject: [PATCH 1/8] Started work on guest access --- .gitignore | 1 + composer.json | 2 +- src/Managers/RequestManager.php | 6 ++- src/Proxy.php | 65 +++++++++++++++++++++++++++++++-- src/ProxyAux.php | 1 + src/config/proxy.php | 33 ++++++++++++++++- 6 files changed, 101 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 510eb6f..1c5433f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store composer.lock /vendor /.idea diff --git a/composer.json b/composer.json index a61c659..01a83de 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "require": { "php": ">=5.5.0", "laravel/framework": "5.2.*|5.3.*", - "guzzlehttp/guzzle": "~5.3" + "guzzlehttp/guzzle": "~6.0" }, "autoload": { "psr-4": { diff --git a/src/Managers/RequestManager.php b/src/Managers/RequestManager.php index 38312a6..ea8cb14 100644 --- a/src/Managers/RequestManager.php +++ b/src/Managers/RequestManager.php @@ -12,6 +12,8 @@ namespace Manukn\LaravelProxify\Managers; +use Log; + use Manukn\LaravelProxify\ProxyAux; use Manukn\LaravelProxify\Models\ProxyResponse; use GuzzleHttp\Client; @@ -138,7 +140,7 @@ private function tryRefreshToken($inputs, $parsedCookie) private function replicateRequest($method, $uri, $inputs) { $guzzleResponse = $this->sendGuzzleRequest($method, $uri, $inputs); - $proxyResponse = new ProxyResponse($guzzleResponse->getStatusCode(), $guzzleResponse->getReasonPhrase(), $guzzleResponse->getProtocolVersion(), $this->getResponseContent($guzzleResponse)); + $proxyResponse = new ProxyResponse($guzzleResponse->getStatusCode(), $guzzleResponse->getReasonPhrase(), $guzzleResponse->getProtocolVersion(), self::getResponseContent($guzzleResponse)); return $proxyResponse; } @@ -147,7 +149,7 @@ private function replicateRequest($method, $uri, $inputs) * @param \GuzzleHttp\Message\ResponseInterface $response * @return mixed */ - private function getResponseContent($response) + public static function getResponseContent($response) { switch ($response->getHeader('content-type')) { case 'application/json': diff --git a/src/Proxy.php b/src/Proxy.php index f951eff..bf7e363 100644 --- a/src/Proxy.php +++ b/src/Proxy.php @@ -12,14 +12,19 @@ namespace Manukn\LaravelProxify; +use Log; + use Manukn\LaravelProxify\Exceptions\CookieExpiredException; use Manukn\LaravelProxify\Exceptions\ProxyMissingParamException; use Manukn\LaravelProxify\Managers\CookieManager; use Manukn\LaravelProxify\Managers\RequestManager; use Illuminate\Http\Response; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ClientException; class Proxy { + const CLIENT_ACCESS_TOKEN_CACHE_KEY = 'PROXIFY_CLIENT_ACCESS_TOKEN'; private $callMode = null; private $uriParam = null; @@ -27,6 +32,8 @@ class Proxy private $redirectUri = null; private $clientSecrets = null; private $cookieManager = null; + private $guestAccessTokens = null; + private $clientApiHosts = null; private $useHeader = false; /** @@ -38,6 +45,8 @@ public function __construct($params) $this->redirectUri = $params['redirect_login']; $this->clientSecrets = $params['client_secrets']; $this->useHeader = $params['use_header']; + $this->clientApiHosts = $params['client_api_hosts']; + $this->guestAccessTokens = $params['guest_access_tokens']; $this->cookieManager = new CookieManager($params['cookie_info']); } @@ -66,10 +75,14 @@ public function makeRequest($method, array $inputs, $url) try { $parsedCookie = $this->cookieManager->tryParseCookie($this->callMode); } catch (CookieExpiredException $ex) { - if (isset($this->redirectUri) && !empty($this->redirectUri)) { - return \Redirect::to($this->redirectUri); + $parsedCookie = $this->getGuestAccessToken($url); + + if (!$parseCookie) { + if (isset($this->redirectUri) && !empty($this->redirectUri)) { + return \Redirect::to($this->redirectUri); + } + throw $ex; } - throw $ex; } } @@ -122,6 +135,52 @@ private function setApiResponse($proxyResponse, $cookie) return $response; } + + /** + * Tries to retrieve a guest access token for anonymous access, if possible. + */ + private function getGuestAccessToken($url) { + $hostName = explode('/', $url); + $hostName = $hostName[0]; + if (!isset($this->clientApiHosts[$hostName])) return null; + $clientId = $this->clientApiHosts[$hostName]; + + $success; + $accessToken = apcu_fetch(self::CLIENT_ACCESS_TOKEN_CACHE_KEY.'_'.$clientId, $success); + + if (!$success || !$accessToken) { + Log::info("Requesting client access token from API for client ID ".$clientId); + $accessToken = $this->requestClientAccessToken($clientId); + Log::info($accessToken); + } + } + + private function requestClientAccessToken($clientId) { + $tokenUrl = $this->guestAccessTokens[$clientId]; + $clientSecret = $this->clientSecrets[$clientId]; + $client = new Client(); + $result = $client->post($tokenUrl, [ + 'form_params' => [ + ProxyAux::CLIENT_ID => $clientId, + ProxyAux::CLIENT_SECRET => $clientSecret, + ProxyAux::GRANT_TYPE => ProxyAux::CLIENT_CREDENTIALS + ] + ]); + + try { + $response = $client->send($request); + } catch (ClientException $ex) { + $response = $ex->getResponse(); + } + + if ($response->getStatusCode() != 200) { + Log::error('Cannot get access token for '.$clientId.'. Server responds with status code '.$result->getStatusCode()); + abort($result->getStatusCode()); + return; + } + + return RequestManager::getResponseContent($result); + } /** * @return array diff --git a/src/ProxyAux.php b/src/ProxyAux.php index 16a746b..26a9d1b 100644 --- a/src/ProxyAux.php +++ b/src/ProxyAux.php @@ -22,6 +22,7 @@ class ProxyAux const REFRESH_TOKEN = 'refresh_token'; const CLIENT_ID = 'client_id'; const CLIENT_SECRET = 'client_secret'; + const CLIENT_CREDENTIALS = 'client_credentials'; const COOKIE_URI = 'uri'; const COOKIE_METHOD = 'method'; const PASSWORD_GRANT = 'password'; diff --git a/src/config/proxy.php b/src/config/proxy.php index 5c975c0..15a90f8 100644 --- a/src/config/proxy.php +++ b/src/config/proxy.php @@ -56,7 +56,7 @@ | */ 'use_header' => false, - + /* |-------------------------------------------------------------------------- | List of client secret @@ -69,4 +69,35 @@ 'client_1' => 'abc123', 'client_2' => 'def456' ], + + /* + |-------------------------------------------------------------------------- + | Access token used for guest users + |-------------------------------------------------------------------------- + | + | Enables the proxy to make an authenticated request on behalf of an anonymous user, by using + | an access token that is automatically retrieved using the client credentials grant. + | + | The client app access token is never forwarded to the user's browser. + | Instead it is kept server-side and stored as a cached variable using the APCU extension. + | + */ + 'guest_access_tokens' => [ + // Associates client ID with OAuth token endpoint URL + 'client_1' => 'http://auth.example-domain.xyz/oauth/token' + ], + + /* + |-------------------------------------------------------------------------- + | List of API host names associated with each client + |-------------------------------------------------------------------------- + | + | Defines API host names for each client ID. Must be specified if 'guest_access_token' is also + | used. + | + */ + 'client_api_hosts' => [ + 'api.example-domain.xyz' => 'client_1', + 'api.some-other-domain.xyz' => 'client_2' + ] ]; From 7d63e3565583a8c24fed64716888f7af0842974a Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Tue, 3 Jan 2017 13:30:53 -0800 Subject: [PATCH 2/8] Implement guest access token feature. Fixed wrong content type bug --- README.md | 2 +- src/Exceptions/UnauthorizedException.php | 37 ++++++++++++++++++ src/Managers/RequestManager.php | 40 +++++++++++--------- src/Proxy.php | 48 +++++++++++++++--------- 4 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 src/Exceptions/UnauthorizedException.php diff --git a/README.md b/README.md index 56d8687..1b87c5e 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ In the `app/config/routes.php` add a new endpoint like: ```php Route::any('proxify/{url?}', function ($url) { - return Proxify::makeRequest(Request::method(), Request::all(), $url); + return Proxify::makeRequest(request(), $url); })->where('url', '(.*)'); ``` diff --git a/src/Exceptions/UnauthorizedException.php b/src/Exceptions/UnauthorizedException.php new file mode 100644 index 0000000..a811b83 --- /dev/null +++ b/src/Exceptions/UnauthorizedException.php @@ -0,0 +1,37 @@ + + * @copyright Copyright (c) Michele Andreoli + * @author Rik Schreurs + * @copyright Copyright (c) Rik Schreurs + * @license http://mit-license.org/ + * @link https://github.com/manukn/oauth2-server-proxify-laravel + */ + +namespace Manukn\LaravelProxify\Exceptions; + +use Symfony\Component\HttpKernel\Exception\HttpException; + +/** + * Exception class + */ +class UnauthorizedException extends HttpException +{ + /** + * Constructor. + * + * @param string $message The internal exception message + * @param \Exception $previous The previous exception + * @param int $code The internal exception code + */ + public function __construct($message = null, \Exception $previous = null, $code = 0) + { + if (!$message) { + $message = \Lang::get('api-proxy-laravel::messages.proxy_cookie_expired'); + } + + parent::__construct(403, $message, $previous, array(), $code); + } +} diff --git a/src/Managers/RequestManager.php b/src/Managers/RequestManager.php index ea8cb14..5b167f6 100644 --- a/src/Managers/RequestManager.php +++ b/src/Managers/RequestManager.php @@ -16,6 +16,7 @@ use Manukn\LaravelProxify\ProxyAux; use Manukn\LaravelProxify\Models\ProxyResponse; +use Illuminate\Http\Request; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; use Manukn\LaravelProxify\Exceptions\MissingClientSecretException; @@ -24,6 +25,7 @@ class RequestManager { private $uri = null; + private $request = null; private $method = null; private $callMode = null; private $clientSecrets = null; @@ -34,10 +36,11 @@ class RequestManager * @param string $callMode * @param CookieManager $cookieManager */ - public function __construct($uri, $method, $clientSecrets, $callMode, $cookieManager) + public function __construct($uri, Request $request, $clientSecrets, $callMode, $cookieManager) { $this->uri = $uri; - $this->method = $method; + $this->method = $request->method(); + $this->request = $request; $this->clientSecrets = $clientSecrets; $this->callMode = $callMode; $this->cookieManager = $cookieManager; @@ -151,12 +154,12 @@ private function replicateRequest($method, $uri, $inputs) */ public static function getResponseContent($response) { - switch ($response->getHeader('content-type')) { + switch ($response->getHeaderLine('content-type')) { case 'application/json': - return $response->json(); - case 'text/xml': - case 'application/xml': - return $response->xml(); + return json_decode($response->getBody(), true); +// case 'text/xml': +// case 'application/xml': +// return $response->xml(); default: return $response->getBody(); } @@ -182,19 +185,20 @@ private function sendGuzzleRequest($method, $uriVal, $inputs) if ($method === 'GET') { $options = array_add($options, 'query', $inputs); } else { - $options = array_add($options, 'body', $inputs); - } - - $request = $client->createRequest($method, $uriVal, $options); - - - try { - $response = $client->send($request); - } catch (ClientException $ex) { - $response = $ex->getResponse(); + $contentType = explode(';', $this->request->header('Content-Type')); + $contentType = trim($contentType[0]); + + if ($this->request->isJson()) { + $options = array_add($options, 'json', $inputs); + } else if (Request::matchesType($contentType, 'application/x-www-form-urlencoded')) { + $options = array_add($options, 'form_params', $inputs); + } else { + // TODO add content type to guzzle headers + $options = array_add($options, 'body', $inputs); + } } - return $response; + return $client->request($method, $uriVal, $options); } /** diff --git a/src/Proxy.php b/src/Proxy.php index bf7e363..83b3a36 100644 --- a/src/Proxy.php +++ b/src/Proxy.php @@ -15,9 +15,11 @@ use Log; use Manukn\LaravelProxify\Exceptions\CookieExpiredException; +use Manukn\LaravelProxify\Exceptions\UnauthorizedException; use Manukn\LaravelProxify\Exceptions\ProxyMissingParamException; use Manukn\LaravelProxify\Managers\CookieManager; use Manukn\LaravelProxify\Managers\RequestManager; +use Illuminate\Http\Request; use Illuminate\Http\Response; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; @@ -58,9 +60,10 @@ public function __construct($params) * @throws ProxyMissingParamException * @throws \Exception */ - public function makeRequest($method, array $inputs, $url) + public function makeRequest(Request $request, $url) { $this->uri = $url; + $inputs = $request->all(); //Retrieve the call mode from input parameters $this->callMode = $this->getRequestMode($inputs); @@ -71,27 +74,38 @@ public function makeRequest($method, array $inputs, $url) //Read the cookie if exists $parsedCookie = null; + $isGuestAccess = false; + if ($this->callMode !== ProxyAux::MODE_SKIP && $this->callMode !== ProxyAux::MODE_LOGIN) { try { $parsedCookie = $this->cookieManager->tryParseCookie($this->callMode); } catch (CookieExpiredException $ex) { $parsedCookie = $this->getGuestAccessToken($url); - - if (!$parseCookie) { + $isGuestAccess = true; + + if (!$parsedCookie) { if (isset($this->redirectUri) && !empty($this->redirectUri)) { return \Redirect::to($this->redirectUri); } + throw $ex; } } } //Create the new request - $requestManager = new RequestManager($this->uri, $method, $this->clientSecrets, $this->callMode, $this->cookieManager); + $requestManager = new RequestManager($this->uri, $request, $this->clientSecrets, $this->callMode, $this->cookieManager); if ($this->useHeader) { $requestManager->enableHeader(); } + $proxyResponse = $requestManager->executeRequest($inputs, $parsedCookie); + + if ($isGuestAccess && $proxyResponse['statusCode'] == 401) { + Log::warn('Guest access token has expired'); + $parsedCookie = $this->getGuestAccessToken($url, true); + $proxyResponse = $requestManager->executeRequest($inputs, $parsedCookie); + } return $this->setApiResponse($proxyResponse['response'], $proxyResponse['cookie']); } @@ -139,27 +153,31 @@ private function setApiResponse($proxyResponse, $cookie) /** * Tries to retrieve a guest access token for anonymous access, if possible. */ - private function getGuestAccessToken($url) { + private function getGuestAccessToken($url, $force = false) { $hostName = explode('/', $url); $hostName = $hostName[0]; if (!isset($this->clientApiHosts[$hostName])) return null; $clientId = $this->clientApiHosts[$hostName]; $success; - $accessToken = apcu_fetch(self::CLIENT_ACCESS_TOKEN_CACHE_KEY.'_'.$clientId, $success); + $cacheKey = self::CLIENT_ACCESS_TOKEN_CACHE_KEY.'_'.$clientId; + $accessToken = apcu_fetch($cacheKey, $success); - if (!$success || !$accessToken) { + if ($force || !$success || !$accessToken) { Log::info("Requesting client access token from API for client ID ".$clientId); $accessToken = $this->requestClientAccessToken($clientId); - Log::info($accessToken); + $accessToken = $accessToken[ProxyAux::ACCESS_TOKEN]; + apcu_store($cacheKey, $accessToken); } + + return $accessToken; } private function requestClientAccessToken($clientId) { $tokenUrl = $this->guestAccessTokens[$clientId]; $clientSecret = $this->clientSecrets[$clientId]; $client = new Client(); - $result = $client->post($tokenUrl, [ + $response = $client->post($tokenUrl, [ 'form_params' => [ ProxyAux::CLIENT_ID => $clientId, ProxyAux::CLIENT_SECRET => $clientSecret, @@ -167,19 +185,13 @@ private function requestClientAccessToken($clientId) { ] ]); - try { - $response = $client->send($request); - } catch (ClientException $ex) { - $response = $ex->getResponse(); - } - if ($response->getStatusCode() != 200) { - Log::error('Cannot get access token for '.$clientId.'. Server responds with status code '.$result->getStatusCode()); - abort($result->getStatusCode()); + Log::error('Cannot get access token for '.$clientId.'. Server responds with status code '.$response->getStatusCode()); + abort($response->getStatusCode()); return; } - return RequestManager::getResponseContent($result); + return RequestManager::getResponseContent($response); } /** From 5306530f3e9d15f81798983a9e5952cb926f0c03 Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Tue, 3 Jan 2017 13:47:31 -0800 Subject: [PATCH 3/8] Bug fix --- src/Proxy.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Proxy.php b/src/Proxy.php index 83b3a36..ccf8622 100644 --- a/src/Proxy.php +++ b/src/Proxy.php @@ -166,7 +166,6 @@ private function getGuestAccessToken($url, $force = false) { if ($force || !$success || !$accessToken) { Log::info("Requesting client access token from API for client ID ".$clientId); $accessToken = $this->requestClientAccessToken($clientId); - $accessToken = $accessToken[ProxyAux::ACCESS_TOKEN]; apcu_store($cacheKey, $accessToken); } From cacf1256fb95b1deb3cb112d4f3c21035cebcf84 Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Thu, 5 Jan 2017 07:58:49 -0800 Subject: [PATCH 4/8] Trying to fix an issue with AJAX requests --- src/Managers/RequestManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Managers/RequestManager.php b/src/Managers/RequestManager.php index 5b167f6..91e5797 100644 --- a/src/Managers/RequestManager.php +++ b/src/Managers/RequestManager.php @@ -188,7 +188,7 @@ private function sendGuzzleRequest($method, $uriVal, $inputs) $contentType = explode(';', $this->request->header('Content-Type')); $contentType = trim($contentType[0]); - if ($this->request->isJson()) { + if ($this->request->isJson() || $this->request->ajax()) { $options = array_add($options, 'json', $inputs); } else if (Request::matchesType($contentType, 'application/x-www-form-urlencoded')) { $options = array_add($options, 'form_params', $inputs); From 3ded226045bbb0474040199cc3c84d5b91a77909 Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Thu, 5 Jan 2017 08:13:23 -0800 Subject: [PATCH 5/8] Made sure that original proxy request is forwarded with content and content-type --- src/Managers/RequestManager.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Managers/RequestManager.php b/src/Managers/RequestManager.php index 91e5797..eae5308 100644 --- a/src/Managers/RequestManager.php +++ b/src/Managers/RequestManager.php @@ -185,17 +185,11 @@ private function sendGuzzleRequest($method, $uriVal, $inputs) if ($method === 'GET') { $options = array_add($options, 'query', $inputs); } else { - $contentType = explode(';', $this->request->header('Content-Type')); - $contentType = trim($contentType[0]); - - if ($this->request->isJson() || $this->request->ajax()) { - $options = array_add($options, 'json', $inputs); - } else if (Request::matchesType($contentType, 'application/x-www-form-urlencoded')) { - $options = array_add($options, 'form_params', $inputs); - } else { - // TODO add content type to guzzle headers - $options = array_add($options, 'body', $inputs); - } + $contentType = $this->request->header('Content-Type'); + $options = array_add($options, 'headers', [ + 'Content-Type' => $contentType + ]); + $options = array_add($options, 'body', $this->request->getContent()); } return $client->request($method, $uriVal, $options); From 5d50d17833e410ae665302f0edd8924c34029798 Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Mon, 9 Jan 2017 12:56:49 -0800 Subject: [PATCH 6/8] Several bugfixes --- src/Managers/RequestManager.php | 27 ++++++++++++++++++++++----- src/Proxy.php | 14 +++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/Managers/RequestManager.php b/src/Managers/RequestManager.php index eae5308..c75b359 100644 --- a/src/Managers/RequestManager.php +++ b/src/Managers/RequestManager.php @@ -185,14 +185,31 @@ private function sendGuzzleRequest($method, $uriVal, $inputs) if ($method === 'GET') { $options = array_add($options, 'query', $inputs); } else { - $contentType = $this->request->header('Content-Type'); - $options = array_add($options, 'headers', [ - 'Content-Type' => $contentType - ]); + $contentType = explode(';', $this->request->header('Content-Type')); + $contentType = trim($contentType[0]); + + if (Request::matchesType($contentType, 'application/json')) { + $options = array_add($options, 'json', $inputs); + } else if (Request::matchesType($contentType, 'application/x-www-form-urlencoded')) { + $options = array_add($options, 'form_params', $inputs); + } else { + // TODO add content type to guzzle headers + $options = array_add($options, 'headers', [ + 'Content-Type' => $this->request->header('Content-Type') + ]); + $options = array_add($options, 'body', $this->request->getContent()); + } + $options = array_add($options, 'body', $this->request->getContent()); } - return $client->request($method, $uriVal, $options); + try { + return $client->request($method, $uriVal, $options); + } catch (ClientException $ex) { + Log::warning("Got error response from API ".$ex->getMessage()); + + return $ex->getResponse(); + } } /** diff --git a/src/Proxy.php b/src/Proxy.php index ccf8622..81c71d2 100644 --- a/src/Proxy.php +++ b/src/Proxy.php @@ -100,14 +100,15 @@ public function makeRequest(Request $request, $url) } $proxyResponse = $requestManager->executeRequest($inputs, $parsedCookie); + $wrappedResponse = $proxyResponse['response']; - if ($isGuestAccess && $proxyResponse['statusCode'] == 401) { - Log::warn('Guest access token has expired'); + if ($isGuestAccess && $wrappedResponse->getStatusCode() == 401) { + Log::warning('Guest access token has expired'); $parsedCookie = $this->getGuestAccessToken($url, true); $proxyResponse = $requestManager->executeRequest($inputs, $parsedCookie); } - return $this->setApiResponse($proxyResponse['response'], $proxyResponse['cookie']); + return $this->setApiResponse($wrappedResponse, $proxyResponse['cookie']); } /** @@ -154,8 +155,7 @@ private function setApiResponse($proxyResponse, $cookie) * Tries to retrieve a guest access token for anonymous access, if possible. */ private function getGuestAccessToken($url, $force = false) { - $hostName = explode('/', $url); - $hostName = $hostName[0]; + $hostName = parse_url($url, PHP_URL_HOST); if (!isset($this->clientApiHosts[$hostName])) return null; $clientId = $this->clientApiHosts[$hostName]; @@ -169,6 +169,10 @@ private function getGuestAccessToken($url, $force = false) { apcu_store($cacheKey, $accessToken); } + if (!$accessToken) { + Log::error("Could not retrieve client access token for client ID ".$clientId); + } + return $accessToken; } From b81321c0585201b7223b31567691ed8a45d86160 Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Mon, 9 Jan 2017 13:31:32 -0800 Subject: [PATCH 7/8] Refresh token request was incorrectly dispatched --- src/Managers/RequestManager.php | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/Managers/RequestManager.php b/src/Managers/RequestManager.php index c75b359..59f5162 100644 --- a/src/Managers/RequestManager.php +++ b/src/Managers/RequestManager.php @@ -59,10 +59,13 @@ public function enableHeader() public function executeRequest($inputs, $parsedCookie) { $cookie = null; + $contentType = explode(';', $this->request->header('Content-Type')); + $contentType = trim($contentType[0]); + switch ($this->callMode) { case ProxyAux::MODE_LOGIN: $inputs = $this->addLoginExtraParams($inputs); - $proxyResponse = $this->replicateRequest($this->method, $this->uri, $inputs); + $proxyResponse = $this->replicateRequest($this->method, $this->uri, $inputs, $contentType); $clientId = (array_key_exists(ProxyAux::CLIENT_ID, $inputs)) ? $inputs[ProxyAux::CLIENT_ID] : null; $content = $proxyResponse->getContent(); @@ -74,7 +77,7 @@ public function executeRequest($inputs, $parsedCookie) break; case ProxyAux::MODE_TOKEN: $inputs = $this->addTokenExtraParams($inputs, $parsedCookie); - $proxyResponse = $this->replicateRequest($this->method, $this->uri, $inputs); + $proxyResponse = $this->replicateRequest($this->method, $this->uri, $inputs, $contentType); //Get a new access token from refresh token if exists $cookie = null; @@ -90,7 +93,7 @@ public function executeRequest($inputs, $parsedCookie) $cookie = (isset($ret)) ? $ret['cookie'] : $cookie; break; default: - $proxyResponse = $this->replicateRequest($this->method, $this->uri, $inputs); + $proxyResponse = $this->replicateRequest($this->method, $this->uri, $inputs, $contentType); } return array( @@ -111,7 +114,7 @@ private function tryRefreshToken($inputs, $parsedCookie) //Get a new access token from refresh token $inputs = $this->removeTokenExtraParams($inputs); $params = $this->addRefreshExtraParams(array(), $parsedCookie); - $proxyResponse = $this->replicateRequest($parsedCookie[ProxyAux::COOKIE_METHOD], $parsedCookie[ProxyAux::COOKIE_URI], $params); + $proxyResponse = $this->replicateRequest($parsedCookie[ProxyAux::COOKIE_METHOD], $parsedCookie[ProxyAux::COOKIE_URI], $params, 'application/x-www-form-urlencoded'); $content = $proxyResponse->getContent(); if ($proxyResponse->getStatusCode() === 200 && array_key_exists(ProxyAux::ACCESS_TOKEN, $content)) { @@ -140,9 +143,9 @@ private function tryRefreshToken($inputs, $parsedCookie) * @param $inputs * @return ProxyResponse */ - private function replicateRequest($method, $uri, $inputs) + private function replicateRequest($method, $uri, $inputs, $contentType) { - $guzzleResponse = $this->sendGuzzleRequest($method, $uri, $inputs); + $guzzleResponse = $this->sendGuzzleRequest($method, $uri, $inputs, $contentType); $proxyResponse = new ProxyResponse($guzzleResponse->getStatusCode(), $guzzleResponse->getReasonPhrase(), $guzzleResponse->getProtocolVersion(), self::getResponseContent($guzzleResponse)); return $proxyResponse; @@ -171,7 +174,7 @@ public static function getResponseContent($response) * @param $inputs * @return \GuzzleHttp\Message\ResponseInterface */ - private function sendGuzzleRequest($method, $uriVal, $inputs) + private function sendGuzzleRequest($method, $uriVal, $inputs, $contentType) { $options = array(); $client = new Client(); @@ -185,22 +188,16 @@ private function sendGuzzleRequest($method, $uriVal, $inputs) if ($method === 'GET') { $options = array_add($options, 'query', $inputs); } else { - $contentType = explode(';', $this->request->header('Content-Type')); - $contentType = trim($contentType[0]); - if (Request::matchesType($contentType, 'application/json')) { $options = array_add($options, 'json', $inputs); } else if (Request::matchesType($contentType, 'application/x-www-form-urlencoded')) { $options = array_add($options, 'form_params', $inputs); } else { - // TODO add content type to guzzle headers $options = array_add($options, 'headers', [ - 'Content-Type' => $this->request->header('Content-Type') + 'Content-Type' => $contentType ]); - $options = array_add($options, 'body', $this->request->getContent()); + $options = array_add($options, 'body', $inputs); } - - $options = array_add($options, 'body', $this->request->getContent()); } try { From 789e29d03c79f4fed4283c77819d990e83fe185c Mon Sep 17 00:00:00 2001 From: Thomas Iguchi Date: Mon, 9 Jan 2017 13:33:22 -0800 Subject: [PATCH 8/8] Refresh token should be only requested when request was unauthorized --- src/Managers/RequestManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Managers/RequestManager.php b/src/Managers/RequestManager.php index 59f5162..e0e58a4 100644 --- a/src/Managers/RequestManager.php +++ b/src/Managers/RequestManager.php @@ -81,7 +81,7 @@ public function executeRequest($inputs, $parsedCookie) //Get a new access token from refresh token if exists $cookie = null; - if ($proxyResponse->getStatusCode() != 200) { + if ($proxyResponse->getStatusCode() == 401) { if (array_key_exists(ProxyAux::REFRESH_TOKEN, $parsedCookie)) { $ret = $this->tryRefreshToken($inputs, $parsedCookie); } else {