You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
4.9 KiB
184 lines
4.9 KiB
<?php |
|
/** |
|
* @link http://www.yiiframework.com/ |
|
* @copyright Copyright (c) 2008 Yii Software LLC |
|
* @license http://www.yiiframework.com/license/ |
|
*/ |
|
|
|
namespace yii\authclient; |
|
|
|
use Yii; |
|
use yii\base\Exception; |
|
|
|
/** |
|
* OAuth2 serves as a client for the OAuth 2 flow. |
|
* |
|
* In oder to acquire access token perform following sequence: |
|
* |
|
* ~~~ |
|
* use yii\authclient\OAuth2; |
|
* |
|
* $oauthClient = new OAuth2(); |
|
* $url = $oauthClient->buildAuthUrl(); // Build authorization URL |
|
* Yii::$app->getResponse()->redirect($url); // Redirect to authorization URL. |
|
* // After user returns at our site: |
|
* $code = $_GET['code']; |
|
* $accessToken = $oauthClient->fetchAccessToken($code); // Get access token |
|
* ~~~ |
|
* |
|
* @see http://oauth.net/2/ |
|
* |
|
* @author Paul Klimov <klimov.paul@gmail.com> |
|
* @since 2.0 |
|
*/ |
|
class OAuth2 extends BaseOAuth |
|
{ |
|
/** |
|
* @var string protocol version. |
|
*/ |
|
public $version = '2.0'; |
|
/** |
|
* @var string OAuth client ID. |
|
*/ |
|
public $clientId; |
|
/** |
|
* @var string OAuth client secret. |
|
*/ |
|
public $clientSecret; |
|
/** |
|
* @var string token request URL endpoint. |
|
*/ |
|
public $tokenUrl; |
|
|
|
/** |
|
* Composes user authorization URL. |
|
* @param array $params additional auth GET params. |
|
* @return string authorization URL. |
|
*/ |
|
public function buildAuthUrl(array $params = []) |
|
{ |
|
$defaultParams = [ |
|
'client_id' => $this->clientId, |
|
'response_type' => 'code', |
|
'redirect_uri' => $this->getReturnUrl(), |
|
'xoauth_displayname' => Yii::$app->name, |
|
]; |
|
if (!empty($this->scope)) { |
|
$defaultParams['scope'] = $this->scope; |
|
} |
|
return $this->composeUrl($this->authUrl, array_merge($defaultParams, $params)); |
|
} |
|
|
|
/** |
|
* Fetches access token from authorization code. |
|
* @param string $authCode authorization code, usually comes at $_GET['code']. |
|
* @param array $params additional request params. |
|
* @return OAuthToken access token. |
|
*/ |
|
public function fetchAccessToken($authCode, array $params = []) |
|
{ |
|
$defaultParams = [ |
|
'client_id' => $this->clientId, |
|
'client_secret' => $this->clientSecret, |
|
'code' => $authCode, |
|
'grant_type' => 'authorization_code', |
|
'redirect_uri' => $this->getReturnUrl(), |
|
]; |
|
$response = $this->sendRequest('POST', $this->tokenUrl, array_merge($defaultParams, $params)); |
|
$token = $this->createToken(['params' => $response]); |
|
$this->setAccessToken($token); |
|
return $token; |
|
} |
|
|
|
/** |
|
* Composes HTTP request CUrl options, which will be merged with the default ones. |
|
* @param string $method request type. |
|
* @param string $url request URL. |
|
* @param array $params request params. |
|
* @return array CUrl options. |
|
* @throws Exception on failure. |
|
*/ |
|
protected function composeRequestCurlOptions($method, $url, array $params) |
|
{ |
|
$curlOptions = []; |
|
switch ($method) { |
|
case 'GET': { |
|
$curlOptions[CURLOPT_URL] = $this->composeUrl($url, $params); |
|
break; |
|
} |
|
case 'POST': { |
|
$curlOptions[CURLOPT_POST] = true; |
|
$curlOptions[CURLOPT_HTTPHEADER] = ['Content-type: application/x-www-form-urlencoded']; |
|
$curlOptions[CURLOPT_POSTFIELDS] = http_build_query($params, '', '&', PHP_QUERY_RFC3986); |
|
break; |
|
} |
|
case 'HEAD': |
|
case 'PUT': |
|
case 'DELETE': { |
|
$curlOptions[CURLOPT_CUSTOMREQUEST] = $method; |
|
if (!empty($params)) { |
|
$curlOptions[CURLOPT_URL] = $this->composeUrl($url, $params); |
|
} |
|
break; |
|
} |
|
default: { |
|
throw new Exception("Unknown request method '{$method}'."); |
|
} |
|
} |
|
return $curlOptions; |
|
} |
|
|
|
/** |
|
* Performs request to the OAuth API. |
|
* @param OAuthToken $accessToken actual access token. |
|
* @param string $url absolute API URL. |
|
* @param string $method request method. |
|
* @param array $params request parameters. |
|
* @return array API response. |
|
* @throws Exception on failure. |
|
*/ |
|
protected function apiInternal($accessToken, $url, $method, array $params) |
|
{ |
|
$params['access_token'] = $accessToken->getToken(); |
|
return $this->sendRequest($method, $url, $params); |
|
} |
|
|
|
/** |
|
* Gets new auth token to replace expired one. |
|
* @param OAuthToken $token expired auth token. |
|
* @return OAuthToken new auth token. |
|
*/ |
|
public function refreshAccessToken(OAuthToken $token) |
|
{ |
|
$params = [ |
|
'client_id' => $this->clientId, |
|
'client_secret' => $this->clientSecret, |
|
'grant_type' => 'refresh_token' |
|
]; |
|
$params = array_merge($token->getParams(), $params); |
|
$response = $this->sendRequest('POST', $this->tokenUrl, $params); |
|
return $response; |
|
} |
|
|
|
/** |
|
* Composes default {@link returnUrl} value. |
|
* @return string return URL. |
|
*/ |
|
protected function defaultReturnUrl() |
|
{ |
|
$params = $_GET; |
|
unset($params['code']); |
|
return Yii::$app->getUrlManager()->createAbsoluteUrl(Yii::$app->controller->getRoute(), $params); |
|
} |
|
|
|
/** |
|
* Creates token from its configuration. |
|
* @param array $tokenConfig token configuration. |
|
* @return OAuthToken token instance. |
|
*/ |
|
protected function createToken(array $tokenConfig = []) |
|
{ |
|
$tokenConfig['tokenParamKey'] = 'access_token'; |
|
return parent::createToken($tokenConfig); |
|
} |
|
} |