Skip to content

Commit 0d5e7b5

Browse files
committed
Add Instagram socialite provider
1 parent c33ae40 commit 0d5e7b5

File tree

3 files changed

+134
-12
lines changed

3 files changed

+134
-12
lines changed

config/laravel-oauth.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,13 @@
2222
|
2323
| Here you can specify the specific provider you need for your application
2424
| Supported: "facebook", "google", "github", "twitter", "linkedin", "bitbucket"
25+
| "instagram"
2526
|
2627
*/
2728

2829
'providers' => [
2930
'facebook' => true,
3031
'google' => true,
31-
'github' => true,
32-
33-
//'twitter' => true,
34-
//'linkedin' => true,
35-
//'bitbucket' => true,
3632
],
3733

3834
/*

src/LaravelOAuthServiceProvider.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Mckenziearts\LaravelOAuth;
44

55
use Illuminate\Support\ServiceProvider;
6+
use Mckenziearts\LaravelOAuth\Providers\InstagramProvider;
67

78
class LaravelOAuthServiceProvider extends ServiceProvider
89
{
@@ -15,25 +16,21 @@ public function boot()
1516
{
1617
$this->loadTranslationsFrom(__DIR__.'/Lang', 'laravel-oauth');
1718

18-
// Publishing assets.
1919
$this->publishes([
2020
__DIR__.'/../public/assets' => public_path('vendor/mckenziearts/laravel-oauth/assets'),
2121
], 'laravel-oauth.assets');
22-
23-
// Publishing the migrations.
2422
$this->publishes([
2523
__DIR__.'/../migrations/' => database_path('migrations'),
2624
], 'laravel-oauth.migrations');
27-
28-
// Publishing the configuration file.
2925
$this->publishes([
3026
__DIR__.'/../config/laravel-oauth.php' => config_path('laravel-oauth.php'),
3127
], 'laravel-oauth.config');
32-
33-
// Publishing the translation files.
3428
$this->publishes([
3529
__DIR__.'/Lang' => resource_path('lang/vendor/mckenziearts'),
3630
], 'laravel-oauth.views');
31+
32+
// Boot all new OAuth 2 Provider added to Socialite
33+
$this->bootInstagramSocialite();
3734
}
3835

3936
/**
@@ -67,6 +64,21 @@ public function register()
6764
$loader->alias('LaravelSocialite', \Mckenziearts\LaravelOAuth\Facades\LaravelSocialite::class);
6865
}
6966

67+
/**
68+
* Add Instagram to Socialite
69+
*/
70+
private function bootInstagramSocialite()
71+
{
72+
$socialite = $this->app->make(\Laravel\Socialite\Contracts\Factory::class);
73+
$socialite->extend(
74+
'instagram',
75+
function ($app) use ($socialite) {
76+
$config = $app['config']['services.instagram'];
77+
return $socialite->buildProvider(InstagramProvider::class, $config);
78+
}
79+
);
80+
}
81+
7082
/**
7183
* Get the services provided by the provider.
7284
*
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
namespace Mckenziearts\LaravelOAuth\Providers;
4+
5+
use Laravel\Socialite\Two\AbstractProvider;
6+
use Laravel\Socialite\Two\ProviderInterface;
7+
use Laravel\Socialite\Two\User;
8+
9+
class InstagramProvider extends AbstractProvider implements ProviderInterface
10+
{
11+
/**
12+
* {@inheritdoc}
13+
*/
14+
protected $scopeSeparator = ' ';
15+
16+
/**
17+
* {@inheritdoc}
18+
*/
19+
protected $scopes = ['basic'];
20+
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
protected function getAuthUrl($state)
25+
{
26+
return $this->buildAuthUrlFromBase(
27+
'https://api.instagram.com/oauth/authorize', $state
28+
);
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
protected function getTokenUrl()
35+
{
36+
return 'https://api.instagram.com/oauth/access_token';
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
protected function getUserByToken($token)
43+
{
44+
$endpoint = '/users/self';
45+
$query = [
46+
'access_token' => $token,
47+
];
48+
$signature = $this->generateSignature($endpoint, $query);
49+
50+
$query['sig'] = $signature;
51+
$response = $this->getHttpClient()->get(
52+
'https://api.instagram.com/v1/users/self', [
53+
'query' => $query,
54+
'headers' => [
55+
'Accept' => 'application/json',
56+
],
57+
]);
58+
59+
return json_decode($response->getBody()->getContents(), true)['data'];
60+
}
61+
62+
/**
63+
* {@inheritdoc}
64+
*/
65+
protected function mapUserToObject(array $user)
66+
{
67+
return (new User())->setRaw($user)->map([
68+
'id' => $user['id'],
69+
'nickname' => $user['username'],
70+
'name' => $user['full_name'],
71+
'email' => null,
72+
'avatar' => $user['profile_picture'],
73+
]);
74+
}
75+
76+
/**
77+
* {@inheritdoc}
78+
*/
79+
public function getAccessToken($code)
80+
{
81+
$response = $this->getHttpClient()->post($this->getTokenUrl(), [
82+
'form_params' => $this->getTokenFields($code),
83+
]);
84+
85+
$this->credentialsResponseBody = json_decode($response->getBody(), true);
86+
87+
return $this->parseAccessToken($response->getBody());
88+
}
89+
90+
/**
91+
* {@inheritdoc}
92+
*/
93+
protected function getTokenFields($code)
94+
{
95+
return array_merge(parent::getTokenFields($code), [
96+
'grant_type' => 'authorization_code',
97+
]);
98+
}
99+
100+
/**
101+
* Allows compatibility for signed API requests.
102+
*/
103+
protected function generateSignature($endpoint, array $params)
104+
{
105+
$sig = $endpoint;
106+
ksort($params);
107+
foreach ($params as $key => $val) {
108+
$sig .= "|$key=$val";
109+
}
110+
$signing_key = $this->clientSecret;
111+
112+
return hash_hmac('sha256', $sig, $signing_key, false);
113+
}
114+
}

0 commit comments

Comments
 (0)