GitHubProvider.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 Exception;
  12. use Overtrue\Socialite\AccessTokenInterface;
  13. use Overtrue\Socialite\ProviderInterface;
  14. use Overtrue\Socialite\User;
  15. /**
  16. * Class GitHubProvider.
  17. */
  18. class GitHubProvider extends AbstractProvider implements ProviderInterface
  19. {
  20. /**
  21. * The scopes being requested.
  22. *
  23. * @var array
  24. */
  25. protected $scopes = ['user:email'];
  26. /**
  27. * {@inheritdoc}
  28. */
  29. protected function getAuthUrl($state)
  30. {
  31. return $this->buildAuthUrlFromBase('https://github.com/login/oauth/authorize', $state);
  32. }
  33. /**
  34. * {@inheritdoc}
  35. */
  36. protected function getTokenUrl()
  37. {
  38. return 'https://github.com/login/oauth/access_token';
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. protected function getUserByToken(AccessTokenInterface $token)
  44. {
  45. $userUrl = 'https://api.github.com/user?access_token='.$token->getToken();
  46. $response = $this->getHttpClient()->get(
  47. $userUrl, $this->getRequestOptions()
  48. );
  49. $user = json_decode($response->getBody(), true);
  50. if (in_array('user:email', $this->scopes)) {
  51. $user['email'] = $this->getEmailByToken($token);
  52. }
  53. return $user;
  54. }
  55. /**
  56. * Get the email for the given access token.
  57. *
  58. * @param string $token
  59. *
  60. * @return string|null
  61. */
  62. protected function getEmailByToken($token)
  63. {
  64. $emailsUrl = 'https://api.github.com/user/emails?access_token='.$token->getToken();
  65. try {
  66. $response = $this->getHttpClient()->get(
  67. $emailsUrl, $this->getRequestOptions()
  68. );
  69. } catch (Exception $e) {
  70. return;
  71. }
  72. foreach (json_decode($response->getBody(), true) as $email) {
  73. if ($email['primary'] && $email['verified']) {
  74. return $email['email'];
  75. }
  76. }
  77. }
  78. /**
  79. * {@inheritdoc}
  80. */
  81. protected function mapUserToObject(array $user)
  82. {
  83. return new User([
  84. 'id' => $this->arrayItem($user, 'id'),
  85. 'username' => $this->arrayItem($user, 'login'),
  86. 'nickname' => $this->arrayItem($user, 'login'),
  87. 'name' => $this->arrayItem($user, 'name'),
  88. 'email' => $this->arrayItem($user, 'email'),
  89. 'avatar' => $this->arrayItem($user, 'avatar_url'),
  90. ]);
  91. }
  92. /**
  93. * Get the default options for an HTTP request.
  94. *
  95. * @return array
  96. */
  97. protected function getRequestOptions()
  98. {
  99. return [
  100. 'headers' => [
  101. 'Accept' => 'application/vnd.github.v3+json',
  102. ],
  103. ];
  104. }
  105. }