QQ.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. namespace Overtrue\Socialite\Providers;
  3. use Overtrue\Socialite\User;
  4. /**
  5. * @see http://wiki.connect.qq.com/oauth2-0%E7%AE%80%E4%BB%8B [QQ - OAuth 2.0 登录QQ]
  6. */
  7. class QQ extends Base
  8. {
  9. public const NAME = 'qq';
  10. protected string $baseUrl = 'https://graph.qq.com';
  11. protected array $scopes = ['get_user_info'];
  12. protected bool $withUnionId = false;
  13. protected function getAuthUrl(): string
  14. {
  15. return $this->buildAuthUrlFromBase($this->baseUrl.'/oauth2.0/authorize');
  16. }
  17. protected function getTokenUrl(): string
  18. {
  19. return $this->baseUrl.'/oauth2.0/token';
  20. }
  21. /**
  22. * @param string $code
  23. *
  24. * @return array
  25. */
  26. protected function getTokenFields(string $code): array
  27. {
  28. return parent::getTokenFields($code) + [
  29. 'grant_type' => 'authorization_code',
  30. ];
  31. }
  32. /**
  33. * @param string $code
  34. *
  35. * @return array
  36. * @throws \Overtrue\Socialite\Exceptions\AuthorizeFailedException
  37. * @throws \GuzzleHttp\Exception\GuzzleException
  38. */
  39. public function tokenFromCode(string $code): array
  40. {
  41. $response = $this->getHttpClient()->get($this->getTokenUrl(), [
  42. 'query' => $this->getTokenFields($code),
  43. ]);
  44. \parse_str($response->getBody()->getContents(), $token);
  45. return $this->normalizeAccessTokenResponse($token);
  46. }
  47. public function withUnionId(): self
  48. {
  49. $this->withUnionId = true;
  50. return $this;
  51. }
  52. /**
  53. * @param string $token
  54. *
  55. * @return array
  56. * @throws \GuzzleHttp\Exception\GuzzleException
  57. */
  58. protected function getUserByToken(string $token): array
  59. {
  60. $url = $this->baseUrl.'/oauth2.0/me?fmt=json&access_token='.$token;
  61. $this->withUnionId && $url .= '&unionid=1';
  62. $response = $this->getHttpClient()->get($url);
  63. $me = \json_decode($response->getBody()->getContents(), true);
  64. $queries = [
  65. 'access_token' => $token,
  66. 'fmt' => 'json',
  67. 'openid' => $me['openid'],
  68. 'oauth_consumer_key' => $this->getClientId(),
  69. ];
  70. $response = $this->getHttpClient()->get($this->baseUrl.'/user/get_user_info?'.http_build_query($queries));
  71. return (\json_decode($response->getBody()->getContents(), true) ?? []) + [
  72. 'unionid' => $me['unionid'] ?? null,
  73. 'openid' => $me['openid'] ?? null,
  74. ];
  75. }
  76. /**
  77. * @param array $user
  78. *
  79. * @return \Overtrue\Socialite\User
  80. */
  81. protected function mapUserToObject(array $user): User
  82. {
  83. return new User([
  84. 'id' => $user['openid'] ?? null,
  85. 'name' => $user['nickname'] ?? null,
  86. 'nickname' => $user['nickname'] ?? null,
  87. 'email' => $user['email'] ?? null,
  88. 'avatar' => $user['figureurl_qq_2'] ?? null,
  89. ]);
  90. }
  91. }