WeWorkProvider.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /*
  3. * This file is part of the overtrue/socialite.
  4. *
  5. * (c) overtrue <i@overtrue.me>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. namespace Overtrue\Socialite\Providers;
  11. use Overtrue\Socialite\AccessTokenInterface;
  12. use Overtrue\Socialite\ProviderInterface;
  13. use Overtrue\Socialite\User;
  14. /**
  15. * Class WeWorkProvider.
  16. *
  17. * @author mingyoung <mingyoungcheung@gmail.com>
  18. */
  19. class WeWorkProvider extends AbstractProvider implements ProviderInterface
  20. {
  21. /**
  22. * @var string
  23. */
  24. protected $agentId;
  25. /**
  26. * @var bool
  27. */
  28. protected $detailed = false;
  29. /**
  30. * Set agent id.
  31. *
  32. * @param string $agentId
  33. *
  34. * @return $this
  35. */
  36. public function setAgentId($agentId)
  37. {
  38. $this->agentId = $agentId;
  39. return $this;
  40. }
  41. /**
  42. * @param string $agentId
  43. *
  44. * @return $this
  45. */
  46. public function agent($agentId)
  47. {
  48. return $this->setAgentId($agentId);
  49. }
  50. /**
  51. * Return user details.
  52. *
  53. * @return $this
  54. */
  55. public function detailed()
  56. {
  57. $this->detailed = true;
  58. return $this;
  59. }
  60. /**
  61. * @param string $state
  62. *
  63. * @return string
  64. */
  65. protected function getAuthUrl($state)
  66. {
  67. // 网页授权登录
  68. if (!empty($this->scopes)) {
  69. return $this->getOAuthUrl($state);
  70. }
  71. // 第三方网页应用登录(扫码登录)
  72. return $this->getQrConnectUrl($state);
  73. }
  74. /**
  75. * OAuth url.
  76. *
  77. * @param string $state
  78. *
  79. * @return string
  80. */
  81. protected function getOAuthUrl($state)
  82. {
  83. $queries = [
  84. 'appid' => $this->getConfig()->get('client_id'),
  85. 'redirect_uri' => $this->redirectUrl,
  86. 'response_type' => 'code',
  87. 'scope' => $this->formatScopes($this->scopes, $this->scopeSeparator),
  88. 'agentid' => $this->agentId,
  89. 'state' => $state,
  90. ];
  91. return sprintf('https://open.weixin.qq.com/connect/oauth2/authorize?%s#wechat_redirect', http_build_query($queries));
  92. }
  93. /**
  94. * Qr connect url.
  95. *
  96. * @param string $state
  97. *
  98. * @return string
  99. */
  100. protected function getQrConnectUrl($state)
  101. {
  102. $queries = [
  103. 'appid' => $this->getConfig()->get('client_id'),
  104. 'agentid' => $this->agentId,
  105. 'redirect_uri' => $this->redirectUrl,
  106. 'state' => $state,
  107. ];
  108. return 'https://open.work.weixin.qq.com/wwopen/sso/qrConnect?'.http_build_query($queries);
  109. }
  110. protected function getTokenUrl()
  111. {
  112. return null;
  113. }
  114. /**
  115. * @param \Overtrue\Socialite\AccessTokenInterface $token
  116. *
  117. * @return mixed
  118. */
  119. protected function getUserByToken(AccessTokenInterface $token)
  120. {
  121. $userInfo = $this->getUserInfo($token);
  122. if ($this->detailed && isset($userInfo['user_ticket'])) {
  123. return $this->getUserDetail($token, $userInfo['user_ticket']);
  124. }
  125. $this->detailed = false;
  126. return $userInfo;
  127. }
  128. /**
  129. * Get user base info.
  130. *
  131. * @param \Overtrue\Socialite\AccessTokenInterface $token
  132. *
  133. * @return mixed
  134. */
  135. protected function getUserInfo(AccessTokenInterface $token)
  136. {
  137. $response = $this->getHttpClient()->get('https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo', [
  138. 'query' => array_filter([
  139. 'access_token' => $token->getToken(),
  140. 'code' => $this->getCode(),
  141. ]),
  142. ]);
  143. return json_decode($response->getBody(), true);
  144. }
  145. /**
  146. * Get user detail info.
  147. *
  148. * @param \Overtrue\Socialite\AccessTokenInterface $token
  149. * @param $ticket
  150. *
  151. * @return mixed
  152. */
  153. protected function getUserDetail(AccessTokenInterface $token, $ticket)
  154. {
  155. $response = $this->getHttpClient()->post('https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail', [
  156. 'query' => [
  157. 'access_token' => $token->getToken(),
  158. ],
  159. 'json' => [
  160. 'user_ticket' => $ticket,
  161. ],
  162. ]);
  163. return json_decode($response->getBody(), true);
  164. }
  165. /**
  166. * @param array $user
  167. *
  168. * @return \Overtrue\Socialite\User
  169. */
  170. protected function mapUserToObject(array $user)
  171. {
  172. if ($this->detailed) {
  173. return new User([
  174. 'id' => $this->arrayItem($user, 'userid'),
  175. 'name' => $this->arrayItem($user, 'name'),
  176. 'avatar' => $this->arrayItem($user, 'avatar'),
  177. 'email' => $this->arrayItem($user, 'email'),
  178. ]);
  179. }
  180. return new User(array_filter([
  181. 'id' => $this->arrayItem($user, 'UserId') ?: $this->arrayItem($user, 'OpenId'),
  182. 'userId' => $this->arrayItem($user, 'UserId'),
  183. 'openid' => $this->arrayItem($user, 'OpenId'),
  184. 'deviceId' => $this->arrayItem($user, 'DeviceId'),
  185. ]));
  186. }
  187. }