From c8d6a0f5af0008dc0a8655fbefb325e0e44c8d85 Mon Sep 17 00:00:00 2001 From: Dmitry Kuznetsov Date: Thu, 26 Mar 2015 23:09:41 +0300 Subject: [PATCH] Retrieve email from access token For details: https://vk.com/dev/auth_sites --- src/Vkontakte.php | 94 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 6 deletions(-) diff --git a/src/Vkontakte.php b/src/Vkontakte.php index 3e6750a..5fe01c9 100644 --- a/src/Vkontakte.php +++ b/src/Vkontakte.php @@ -9,7 +9,7 @@ use League\OAuth2\Client\Provider\AbstractProvider; class Vkontakte extends AbstractProvider { - public $scopes = []; + public $scopes = ['email']; public $uidKey = 'user_id'; public $responseType = 'json'; @@ -22,10 +22,94 @@ class Vkontakte extends AbstractProvider { return 'https://oauth.vk.com/access_token'; } + + public function getAccessToken($grant = 'authorization_code', $params = []) + { + if (is_string($grant)) { + // PascalCase the grant. E.g: 'authorization_code' becomes 'AuthorizationCode' + $className = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $grant))); + $grant = 'League\\OAuth2\\Client\\Grant\\'.$className; + if (! class_exists($grant)) { + throw new \InvalidArgumentException('Unknown grant "'.$grant.'"'); + } + $grant = new $grant(); + } elseif (! $grant instanceof GrantInterface) { + $message = get_class($grant).' is not an instance of League\OAuth2\Client\Grant\GrantInterface'; + throw new \InvalidArgumentException($message); + } + + $defaultParams = [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'redirect_uri' => $this->redirectUri, + 'grant_type' => $grant, + ]; + + $requestParams = $grant->prepRequestParams($defaultParams, $params); + + try { + switch (strtoupper($this->method)) { + case 'GET': + // @codeCoverageIgnoreStart + // No providers included with this library use get but 3rd parties may + $client = $this->getHttpClient(); + $client->setBaseUrl($this->urlAccessToken() . '?' . $this->httpBuildQuery($requestParams, '', '&')); + $request = $client->get(null, null, $requestParams)->send(); + $response = $request->getBody(); + break; + // @codeCoverageIgnoreEnd + case 'POST': + $client = $this->getHttpClient(); + $client->setBaseUrl($this->urlAccessToken()); + $request = $client->post(null, null, $requestParams)->send(); + $response = $request->getBody(); + break; + // @codeCoverageIgnoreStart + default: + throw new \InvalidArgumentException('Neither GET nor POST is specified for request'); + // @codeCoverageIgnoreEnd + } + } catch (BadResponseException $e) { + // @codeCoverageIgnoreStart + $response = $e->getResponse()->getBody(); + // @codeCoverageIgnoreEnd + } + + switch ($this->responseType) { + case 'json': + $result = json_decode($response, true); + + if (JSON_ERROR_NONE !== json_last_error()) { + $result = []; + } + + break; + case 'string': + parse_str($response, $result); + break; + } + + if (isset($result['error']) && ! empty($result['error'])) { + // @codeCoverageIgnoreStart + throw new IDPException($result); + // @codeCoverageIgnoreEnd + } + + $result = $this->prepareAccessTokenResult($result); + + $accessToken = $grant->handleResponse($result); + + // Add email from response + if (!empty($result['email'])) { + $accessToken->email = $result['email']; + } + return $accessToken; + } public function urlUserDetails(AccessToken $token) { - $fields = ['nickname', + $fields = ['email', + 'nickname', 'screen_name', 'sex', 'bdate', @@ -61,7 +145,7 @@ class Vkontakte extends AbstractProvider $user = new User(); - $email = (isset($response->email)) ? $response->email : null; + $email = (isset($token->email)) ? $token->email : null; $location = (isset($response->country)) ? $response->country : null; $description = (isset($response->status)) ? $response->status : null; @@ -89,9 +173,7 @@ class Vkontakte extends AbstractProvider public function userEmail($response, AccessToken $token) { - $response = $response->response[0]; - - return isset($response->email) && $response->email ? $response->email : null; + return (isset($token->email)) ? $token->email : null; } public function userScreenName($response, AccessToken $token)