├── VKontakteExtendSocialite.php ├── composer.json ├── README.md └── Provider.php /VKontakteExtendSocialite.php: -------------------------------------------------------------------------------- 1 | extendSocialite('vkontakte', Provider::class); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socialiteproviders/vkontakte", 3 | "description": "VKontakte OAuth2 Provider for Laravel Socialite", 4 | "license": "MIT", 5 | "keywords": [ 6 | "laravel", 7 | "oauth", 8 | "provider", 9 | "socialite", 10 | "vkontakte" 11 | ], 12 | "authors": [ 13 | { 14 | "name": "Brian Faust", 15 | "email": "hello@brianfaust.de" 16 | } 17 | ], 18 | "support": { 19 | "issues": "https://github.com/socialiteproviders/providers/issues", 20 | "source": "https://github.com/socialiteproviders/providers", 21 | "docs": "https://socialiteproviders.com/vkontakte" 22 | }, 23 | "require": { 24 | "php": "^8.0", 25 | "ext-json": "*", 26 | "socialiteproviders/manager": "^4.4" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "SocialiteProviders\\VKontakte\\": "" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VKontakte 2 | 3 | ```bash 4 | composer require socialiteproviders/vkontakte 5 | ``` 6 | 7 | ## Register an application 8 | 9 | Add new application at [vk.ru](https://vk.ru/editapp?act=create). 10 | 11 | ## Installation & Basic Usage 12 | 13 | Please see the [Base Installation Guide](https://socialiteproviders.com/usage/), then follow the provider specific instructions below. 14 | 15 | ### Add configuration to `config/services.php` 16 | 17 | ```php 18 | 'vkontakte' => [ 19 | 'client_id' => env('VKONTAKTE_CLIENT_ID'), 20 | 'client_secret' => env('VKONTAKTE_CLIENT_SECRET'), 21 | 'redirect' => env('VKONTAKTE_REDIRECT_URI') 22 | ], 23 | ``` 24 | 25 | ### Add provider event listener 26 | 27 | #### Laravel 11+ 28 | 29 | In Laravel 11, the default `EventServiceProvider` provider was removed. Instead, add the listener using the `listen` method on the `Event` facade, in your `AppServiceProvider` `boot` method. 30 | 31 | * Note: You do not need to add anything for the built-in socialite providers unless you override them with your own providers. 32 | 33 | ```php 34 | Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) { 35 | $event->extendSocialite('vkontakte', \SocialiteProviders\VKontakte\Provider::class); 36 | }); 37 | ``` 38 |
39 | 40 | Laravel 10 or below 41 | 42 | Configure the package's listener to listen for `SocialiteWasCalled` events. 43 | 44 | Add the event to your `listen[]` array in `app/Providers/EventServiceProvider`. See the [Base Installation Guide](https://socialiteproviders.com/usage/) for detailed instructions. 45 | 46 | ```php 47 | protected $listen = [ 48 | \SocialiteProviders\Manager\SocialiteWasCalled::class => [ 49 | // ... other providers 50 | \SocialiteProviders\VKontakte\VKontakteExtendSocialite::class.'@handle', 51 | ], 52 | ]; 53 | ``` 54 |
55 | 56 | ### Usage 57 | 58 | You should now be able to use the provider like you would regularly use Socialite (assuming you have the facade installed): 59 | 60 | ```php 61 | return Socialite::driver('vkontakte')->redirect(); 62 | ``` 63 | 64 | ### Returned User fields 65 | 66 | - ``id`` 67 | - ``nickname`` 68 | - ``name`` 69 | - ``email`` 70 | - ``avatar`` 71 | 72 | ### Reference 73 | 74 | - [Vk.ru API Reference](https://vk.ru/dev/methods) 75 | -------------------------------------------------------------------------------- /Provider.php: -------------------------------------------------------------------------------- 1 | buildAuthUrlFromBase('https://oauth.vk.ru/authorize', $state); 28 | } 29 | 30 | protected function getTokenUrl(): string 31 | { 32 | return 'https://oauth.vk.ru/access_token'; 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | protected function getUserByToken($token) 39 | { 40 | $formToken = []; 41 | 42 | if (is_array($token)) { 43 | $formToken['email'] = $token['email'] ?? null; 44 | 45 | $token = $token['access_token']; 46 | } 47 | 48 | $response = $this->getHttpClient()->get('https://api.vk.ru/method/users.get', [ 49 | RequestOptions::QUERY => [ 50 | 'access_token' => $token, 51 | 'fields' => implode(',', $this->fields), 52 | 'lang' => $this->getConfig('lang', 'en'), 53 | 'v' => self::VERSION, 54 | ], 55 | ]); 56 | 57 | $response = json_decode((string) $response->getBody(), true); 58 | 59 | if (! is_array($response) || ! isset($response['response'][0])) { 60 | throw new RuntimeException(sprintf( 61 | 'Invalid JSON response from VK: %s', $response->getBody() 62 | )); 63 | } 64 | 65 | return array_merge($formToken, $response['response'][0]); 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | */ 71 | public function user() 72 | { 73 | if ($this->hasInvalidState()) { 74 | throw new InvalidStateException; 75 | } 76 | 77 | $response = $this->getAccessTokenResponse($this->getCode()); 78 | 79 | $user = $this->mapUserToObject($this->getUserByToken($response)); 80 | 81 | $this->credentialsResponseBody = $response; 82 | 83 | if ($user instanceof User) { 84 | $user->setAccessTokenResponseBody($this->credentialsResponseBody); 85 | } 86 | 87 | return $user->setToken($this->parseAccessToken($response)) 88 | ->setExpiresIn($this->parseExpiresIn($response)); 89 | } 90 | 91 | /** 92 | * {@inheritdoc} 93 | */ 94 | protected function mapUserToObject(array $user) 95 | { 96 | return (new User)->setRaw($user)->map([ 97 | 'id' => Arr::get($user, 'id'), 98 | 'nickname' => Arr::get($user, 'screen_name'), 99 | 'name' => trim(Arr::get($user, 'first_name').' '.Arr::get($user, 'last_name')), 100 | 'email' => Arr::get($user, 'email'), 101 | 'avatar' => Arr::get($user, 'photo_200'), 102 | ]); 103 | } 104 | 105 | /** 106 | * Set the user fields to request from Vkontakte. 107 | * 108 | * @param array $fields 109 | * @return $this 110 | */ 111 | public function fields(array $fields) 112 | { 113 | $this->fields = $fields; 114 | 115 | return $this; 116 | } 117 | 118 | public static function additionalConfigKeys(): array 119 | { 120 | return ['lang']; 121 | } 122 | } 123 | --------------------------------------------------------------------------------