Taobao.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. namespace Overtrue\Socialite\Providers;
  3. use Overtrue\Socialite\User;
  4. /**
  5. * @see https://open.taobao.com/doc.htm?docId=102635&docType=1&source=search [Taobao - OAuth 2.0 授权登录]
  6. */
  7. class Taobao extends Base
  8. {
  9. public const NAME = 'taobao';
  10. protected string $baseUrl = 'https://oauth.taobao.com';
  11. protected string $gatewayUrl = 'https://eco.taobao.com/router/rest';
  12. protected string $view = 'web';
  13. protected array $scopes = ['user_info'];
  14. public function withView(string $view): self
  15. {
  16. $this->view = $view;
  17. return $this;
  18. }
  19. protected function getAuthUrl(): string
  20. {
  21. return $this->buildAuthUrlFromBase($this->baseUrl.'/authorize');
  22. }
  23. public function getCodeFields(): array
  24. {
  25. return [
  26. 'client_id' => $this->getClientId(),
  27. 'redirect_uri' => $this->redirectUrl,
  28. 'view' => $this->view,
  29. 'response_type' => 'code',
  30. ];
  31. }
  32. protected function getTokenUrl(): string
  33. {
  34. return $this->baseUrl.'/token';
  35. }
  36. /**
  37. * @param string $code
  38. *
  39. * @return array
  40. */
  41. protected function getTokenFields($code): array
  42. {
  43. return parent::getTokenFields($code) + ['grant_type' => 'authorization_code', 'view' => $this->view];
  44. }
  45. /**
  46. * @param string $code
  47. *
  48. * @return array
  49. * @throws \GuzzleHttp\Exception\GuzzleException
  50. * @throws \Overtrue\Socialite\Exceptions\AuthorizeFailedException
  51. */
  52. public function tokenFromCode(string $code): array
  53. {
  54. $response = $this->getHttpClient()->post($this->getTokenUrl(), [
  55. 'query' => $this->getTokenFields($code),
  56. ]);
  57. return $this->normalizeAccessTokenResponse($response->getBody()->getContents());
  58. }
  59. /**
  60. * @param string $token
  61. * @param array|null $query
  62. *
  63. * @return array
  64. * @throws \GuzzleHttp\Exception\GuzzleException
  65. */
  66. protected function getUserByToken(string $token, ?array $query = []): array
  67. {
  68. $response = $this->getHttpClient()->post($this->getUserInfoUrl($this->gatewayUrl, $token));
  69. return \json_decode($response->getBody()->getContents(), true) ?? [];
  70. }
  71. /**
  72. * @param array $user
  73. *
  74. * @return \Overtrue\Socialite\User
  75. */
  76. protected function mapUserToObject(array $user): User
  77. {
  78. return new User([
  79. 'id' => $user['open_id'] ?? null,
  80. 'nickname' => $user['nick'] ?? null,
  81. 'name' => $user['nick'] ?? null,
  82. 'avatar' => $user['avatar'] ?? null,
  83. 'email' => $user['email'] ?? null,
  84. ]);
  85. }
  86. /**
  87. * @param array $params
  88. *
  89. * @return string
  90. */
  91. protected function generateSign(array $params)
  92. {
  93. ksort($params);
  94. $stringToBeSigned = $this->getConfig()->get('client_secret');
  95. foreach ($params as $k => $v) {
  96. if (!is_array($v) && '@' != substr($v, 0, 1)) {
  97. $stringToBeSigned .= "$k$v";
  98. }
  99. }
  100. $stringToBeSigned .= $this->getConfig()->get('client_secret');
  101. return strtoupper(md5($stringToBeSigned));
  102. }
  103. /**
  104. * @param string $token
  105. * @param array $apiFields
  106. *
  107. * @return array
  108. */
  109. protected function getPublicFields(string $token, array $apiFields = [])
  110. {
  111. $fields = [
  112. 'app_key' => $this->getClientId(),
  113. 'sign_method' => 'md5',
  114. 'session' => $token,
  115. 'timestamp' => \date('Y-m-d H:i:s'),
  116. 'v' => '2.0',
  117. 'format' => 'json',
  118. ];
  119. $fields = array_merge($apiFields, $fields);
  120. $fields['sign'] = $this->generateSign($fields);
  121. return $fields;
  122. }
  123. /**
  124. * @param string $url
  125. * @param string $token
  126. *
  127. * @return string
  128. */
  129. protected function getUserInfoUrl(string $url, string $token)
  130. {
  131. $apiFields = ['method' => 'taobao.miniapp.userInfo.get'];
  132. $query = http_build_query($this->getPublicFields($token, $apiFields), '', '&', $this->encodingType);
  133. return $url.'?'.$query;
  134. }
  135. }