PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/yiisoft/yii2-authclient/OAuth2.php

https://gitlab.com/itlboy/yii2-starter-installed
PHP | 272 lines | 140 code | 36 blank | 96 comment | 10 complexity | 57c0042ead0b78863f9e2782f64141ea MD5 | raw file
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\authclient;
  8. use Yii;
  9. use yii\web\HttpException;
  10. /**
  11. * OAuth2 serves as a client for the OAuth 2 flow.
  12. *
  13. * In oder to acquire access token perform following sequence:
  14. *
  15. * ```php
  16. * use yii\authclient\OAuth2;
  17. *
  18. * $oauthClient = new OAuth2();
  19. * $url = $oauthClient->buildAuthUrl(); // Build authorization URL
  20. * Yii::$app->getResponse()->redirect($url); // Redirect to authorization URL.
  21. * // After user returns at our site:
  22. * $code = $_GET['code'];
  23. * $accessToken = $oauthClient->fetchAccessToken($code); // Get access token
  24. * ```
  25. *
  26. * @see http://oauth.net/2/
  27. * @see https://tools.ietf.org/html/rfc6749
  28. *
  29. * @author Paul Klimov <klimov.paul@gmail.com>
  30. * @since 2.0
  31. */
  32. abstract class OAuth2 extends BaseOAuth
  33. {
  34. /**
  35. * @var string protocol version.
  36. */
  37. public $version = '2.0';
  38. /**
  39. * @var string OAuth client ID.
  40. */
  41. public $clientId;
  42. /**
  43. * @var string OAuth client secret.
  44. */
  45. public $clientSecret;
  46. /**
  47. * @var string token request URL endpoint.
  48. */
  49. public $tokenUrl;
  50. /**
  51. * @var boolean whether to use and validate auth 'state' parameter in authentication flow.
  52. * If enabled - the opaque value will be generated and applied to auth URL to maintain
  53. * state between the request and callback. The authorization server includes this value,
  54. * when redirecting the user-agent back to the client.
  55. * The option is used for preventing cross-site request forgery.
  56. * @since 2.1
  57. */
  58. public $validateAuthState = true;
  59. /**
  60. * Composes user authorization URL.
  61. * @param array $params additional auth GET params.
  62. * @return string authorization URL.
  63. */
  64. public function buildAuthUrl(array $params = [])
  65. {
  66. $defaultParams = [
  67. 'client_id' => $this->clientId,
  68. 'response_type' => 'code',
  69. 'redirect_uri' => $this->getReturnUrl(),
  70. 'xoauth_displayname' => Yii::$app->name,
  71. ];
  72. if (!empty($this->scope)) {
  73. $defaultParams['scope'] = $this->scope;
  74. }
  75. if ($this->validateAuthState) {
  76. $authState = $this->generateAuthState();
  77. $this->setState('authState', $authState);
  78. $defaultParams['state'] = $authState;
  79. }
  80. return $this->composeUrl($this->authUrl, array_merge($defaultParams, $params));
  81. }
  82. /**
  83. * Fetches access token from authorization code.
  84. * @param string $authCode authorization code, usually comes at $_GET['code'].
  85. * @param array $params additional request params.
  86. * @return OAuthToken access token.
  87. * @throws HttpException on invalid auth state in case [[enableStateValidation]] is enabled.
  88. */
  89. public function fetchAccessToken($authCode, array $params = [])
  90. {
  91. if ($this->validateAuthState) {
  92. $authState = $this->getState('authState');
  93. if (!isset($_REQUEST['state']) || empty($authState) || strcmp($_REQUEST['state'], $authState) !== 0) {
  94. throw new HttpException(400, 'Invalid auth state parameter.');
  95. } else {
  96. $this->removeState('authState');
  97. }
  98. }
  99. $defaultParams = [
  100. 'client_id' => $this->clientId,
  101. 'client_secret' => $this->clientSecret,
  102. 'code' => $authCode,
  103. 'grant_type' => 'authorization_code',
  104. 'redirect_uri' => $this->getReturnUrl(),
  105. ];
  106. $request = $this->createRequest()
  107. ->setMethod('POST')
  108. ->setUrl($this->tokenUrl)
  109. ->setData(array_merge($defaultParams, $params));
  110. $response = $this->sendRequest($request);
  111. $token = $this->createToken(['params' => $response]);
  112. $this->setAccessToken($token);
  113. return $token;
  114. }
  115. /**
  116. * @inheritdoc
  117. */
  118. public function applyAccessTokenToRequest($request, $accessToken)
  119. {
  120. $data = $request->getData();
  121. $data['access_token'] = $accessToken->getToken();
  122. $request->setData($data);
  123. }
  124. /**
  125. * Gets new auth token to replace expired one.
  126. * @param OAuthToken $token expired auth token.
  127. * @return OAuthToken new auth token.
  128. */
  129. public function refreshAccessToken(OAuthToken $token)
  130. {
  131. $params = [
  132. 'client_id' => $this->clientId,
  133. 'client_secret' => $this->clientSecret,
  134. 'grant_type' => 'refresh_token'
  135. ];
  136. $params = array_merge($token->getParams(), $params);
  137. $request = $this->createRequest()
  138. ->setMethod('POST')
  139. ->setUrl($this->tokenUrl)
  140. ->setData($params);
  141. $response = $this->sendRequest($request);
  142. $token = $this->createToken(['params' => $response]);
  143. $this->setAccessToken($token);
  144. return $token;
  145. }
  146. /**
  147. * Composes default [[returnUrl]] value.
  148. * @return string return URL.
  149. */
  150. protected function defaultReturnUrl()
  151. {
  152. $params = $_GET;
  153. unset($params['code']);
  154. unset($params['state']);
  155. $params[0] = Yii::$app->controller->getRoute();
  156. return Yii::$app->getUrlManager()->createAbsoluteUrl($params);
  157. }
  158. /**
  159. * Generates the auth state value.
  160. * @return string auth state value.
  161. * @since 2.1
  162. */
  163. protected function generateAuthState()
  164. {
  165. $baseString = get_class($this) . '-' . time();
  166. if (Yii::$app->has('session')) {
  167. $baseString .= '-' . Yii::$app->session->getId();
  168. }
  169. return hash('sha256', uniqid($baseString, true));
  170. }
  171. /**
  172. * Creates token from its configuration.
  173. * @param array $tokenConfig token configuration.
  174. * @return OAuthToken token instance.
  175. */
  176. protected function createToken(array $tokenConfig = [])
  177. {
  178. $tokenConfig['tokenParamKey'] = 'access_token';
  179. return parent::createToken($tokenConfig);
  180. }
  181. /**
  182. * Authenticate OAuth client directly at the provider without third party (user) involved,
  183. * using 'client_credentials' grant type.
  184. * @see http://tools.ietf.org/html/rfc6749#section-4.4
  185. * @param array $params additional request params.
  186. * @return OAuthToken access token.
  187. */
  188. public function authenticateClient($params = [])
  189. {
  190. $defaultParams = [
  191. 'client_id' => $this->clientId,
  192. 'client_secret' => $this->clientSecret,
  193. 'grant_type' => 'client_credentials',
  194. ];
  195. if (!empty($this->scope)) {
  196. $defaultParams['scope'] = $this->scope;
  197. }
  198. $request = $this->createRequest()
  199. ->setMethod('POST')
  200. ->setUrl($this->tokenUrl)
  201. ->setData(array_merge($defaultParams, $params));
  202. $response = $this->sendRequest($request);
  203. $token = $this->createToken(['params' => $response]);
  204. $this->setAccessToken($token);
  205. return $token;
  206. }
  207. /**
  208. * Authenticates user directly by 'username/password' pair, using 'password' grant type.
  209. * @see https://tools.ietf.org/html/rfc6749#section-4.3
  210. * @param string $username user name.
  211. * @param string $password user password.
  212. * @param array $params additional request params.
  213. * @return OAuthToken access token.
  214. */
  215. public function authenticateUser($username, $password, $params = [])
  216. {
  217. $defaultParams = [
  218. 'client_id' => $this->clientId,
  219. 'client_secret' => $this->clientSecret,
  220. 'grant_type' => 'password',
  221. 'username' => $username,
  222. 'password' => $password,
  223. ];
  224. if (!empty($this->scope)) {
  225. $defaultParams['scope'] = $this->scope;
  226. }
  227. $request = $this->createRequest()
  228. ->setMethod('POST')
  229. ->setUrl($this->tokenUrl)
  230. ->setData(array_merge($defaultParams, $params));
  231. $response = $this->sendRequest($request);
  232. $token = $this->createToken(['params' => $response]);
  233. $this->setAccessToken($token);
  234. return $token;
  235. }
  236. }