Skip to content

Commit 1a4f0ac

Browse files
committed
Add login process
1 parent 28e124f commit 1a4f0ac

16 files changed

Lines changed: 393 additions & 60 deletions

examples/getMediasWithLogin.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
require __DIR__ . '/../vendor/autoload.php';
4+
5+
$cache = new Instagram\Storage\CacheManager(__DIR__ . '/../cache/');
6+
7+
try {
8+
9+
$api = new Instagram\Api($cache);
10+
$api->login('username', 'password');
11+
$api->setUserName('pgrimaud');
12+
13+
// First page
14+
15+
/** @var \Instagram\Hydrator\Component\Feed $feed */
16+
$feed = $api->getFeed();
17+
18+
echo '============================' . "\n";
19+
echo 'User Informations : ' . "\n";
20+
echo '============================' . "\n\n";
21+
22+
echo 'ID : ' . $feed->getId() . "\n";
23+
echo 'Full Name : ' . $feed->getFullName() . "\n";
24+
echo 'UserName : ' . $feed->getUserName() . "\n";
25+
echo 'Following : ' . $feed->getFollowing() . "\n";
26+
echo 'Followers : ' . $feed->getFollowers() . "\n\n";
27+
28+
echo '============================' . "\n";
29+
echo 'Medias first page : ' . "\n";
30+
echo '============================' . "\n\n";
31+
32+
/** @var \Instagram\Hydrator\Component\Media $media */
33+
foreach ($feed->getMedias() as $media) {
34+
echo 'ID : ' . $media->getId() . "\n";
35+
echo 'Caption : ' . $media->getCaption() . "\n";
36+
echo 'Link : ' . $media->getLink() . "\n";
37+
echo 'Likes : ' . $media->getLikes() . "\n";
38+
echo 'Date : ' . $media->getDate()->format('Y-m-d h:i:s') . "\n";
39+
echo '============================' . "\n";
40+
}
41+
42+
// Second page
43+
44+
$api->setEndCursor($feed->getEndCursor());
45+
46+
sleep(1); // avoir 429 Rate limit from Instagram
47+
48+
$feed = $api->getFeed();
49+
50+
echo "\n\n";
51+
echo '============================' . "\n";
52+
echo 'Medias third page : ' . "\n";
53+
echo '============================' . "\n\n";
54+
55+
/** @var \Instagram\Hydrator\Component\Media $media */
56+
foreach ($feed->getMedias() as $media) {
57+
echo 'ID : ' . $media->getId() . "\n";
58+
echo 'Caption : ' . $media->getCaption() . "\n";
59+
echo 'Link : ' . $media->getLink() . "\n";
60+
echo 'Likes : ' . $media->getLikes() . "\n";
61+
echo 'Date : ' . $media->getDate()->format('Y-m-d h:i:s') . "\n";
62+
echo '============================' . "\n";
63+
}
64+
65+
// Third page
66+
67+
$api->setEndCursor($feed->getEndCursor());
68+
69+
sleep(1); // avoir 429 Rate limit from Instagram
70+
71+
$feed = $api->getFeed();
72+
73+
echo "\n\n";
74+
echo '============================' . "\n";
75+
echo 'Medias fourth page : ' . "\n";
76+
echo '============================' . "\n\n";
77+
78+
/** @var \Instagram\Hydrator\Component\Media $media */
79+
foreach ($feed->getMedias() as $media) {
80+
echo 'ID : ' . $media->getId() . "\n";
81+
echo 'Caption : ' . $media->getCaption() . "\n";
82+
echo 'Link : ' . $media->getLink() . "\n";
83+
echo 'Likes : ' . $media->getLikes() . "\n";
84+
echo 'Date : ' . $media->getDate()->format('Y-m-d h:i:s') . "\n";
85+
echo '============================' . "\n";
86+
}
87+
88+
// Fourth Page
89+
90+
$api->setEndCursor($feed->getEndCursor());
91+
92+
sleep(1); // avoir 429 Rate limit from Instagram
93+
94+
$feed = $api->getFeed();
95+
96+
echo "\n\n";
97+
echo '============================' . "\n";
98+
echo 'Medias second page : ' . "\n";
99+
echo '============================' . "\n\n";
100+
101+
/** @var \Instagram\Hydrator\Component\Media $media */
102+
foreach ($feed->getMedias() as $media) {
103+
echo 'ID : ' . $media->getId() . "\n";
104+
echo 'Caption : ' . $media->getCaption() . "\n";
105+
echo 'Link : ' . $media->getLink() . "\n";
106+
echo 'Likes : ' . $media->getLikes() . "\n";
107+
echo 'Date : ' . $media->getDate()->format('Y-m-d h:i:s') . "\n";
108+
echo '============================' . "\n";
109+
}
110+
111+
// And etc...
112+
113+
} catch (Exception $exception) {
114+
print_r($exception->getMessage());
115+
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
116+
print_r($exception->getMessage());
117+
}
Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,6 @@
2626
echo 'Private Account : ' . ($feed->isPrivate() ? 'Yes' : 'No') . "\n";
2727
echo 'Media Count : ' . $feed->getMediaCount() . "\n\n";
2828

29-
echo '============================' . "\n";
30-
echo 'Medias first page : ' . "\n";
31-
echo '============================' . "\n\n";
32-
33-
/** @var \Instagram\Hydrator\Component\Media $media */
34-
foreach ($feed->getMedias() as $media) {
35-
echo 'ID : ' . $media->getId() . "\n";
36-
echo 'Caption : ' . $media->getCaption() . "\n";
37-
echo 'Link : ' . $media->getLink() . "\n";
38-
echo 'Likes : ' . $media->getLikes() . "\n";
39-
echo 'Date : ' . $media->getDate()->format('Y-m-d h:i:s') . "\n";
40-
echo '============================' . "\n";
41-
}
42-
4329
} catch (Exception $exception) {
4430
print_r($exception->getMessage());
4531
} catch (\GuzzleHttp\Exception\GuzzleException $e) {

examples/getProfileWithLogin.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
require __DIR__ . '/../vendor/autoload.php';
4+
5+
try {
6+
$cache = new Instagram\Storage\CacheManager(__DIR__ . '/../cache/');
7+
8+
$api = new Instagram\Api($cache);
9+
$api->login('username', 'password');
10+
$api->setUserName('pgrimaud');
11+
12+
// only the first page
13+
/** @var \Instagram\Hydrator\Component\Feed $feed */
14+
$feed = $api->getFeed();
15+
16+
echo '============================' . "\n";
17+
echo 'User Informations : ' . "\n";
18+
echo '============================' . "\n\n";
19+
20+
echo 'ID : ' . $feed->getId() . "\n";
21+
echo 'Full Name : ' . $feed->getFullName() . "\n";
22+
echo 'UserName : ' . $feed->getUserName() . "\n";
23+
echo 'Following : ' . $feed->getFollowing() . "\n";
24+
echo 'Followers : ' . $feed->getFollowers() . "\n";
25+
echo 'Biography : ' . $feed->getBiography() . "\n";
26+
echo 'External Url : ' . $feed->getExternalUrl() . "\n";
27+
echo 'Profile Picture : ' . $feed->getProfilePicture() . "\n";
28+
echo 'Verified Account : ' . ($feed->isVerified() ? 'Yes' : 'No') . "\n";
29+
echo 'Private Account : ' . ($feed->isPrivate() ? 'Yes' : 'No') . "\n";
30+
echo 'Media Count : ' . $feed->getMediaCount() . "\n\n";
31+
32+
} catch (Exception $exception) {
33+
print_r($exception->getMessage());
34+
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
35+
print_r($exception->getMessage());
36+
}

src/Instagram/Api.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace Instagram;
44

55
use GuzzleHttp\Client;
6-
use Instagram\Exception\CacheException;
6+
use GuzzleHttp\Cookie\CookieJar;
7+
use Instagram\Auth\Login;
8+
use Instagram\Exception\InstagramCacheException;
79
use Instagram\Exception\InstagramException;
810
use Instagram\Hydrator\HtmlHydrator;
911
use Instagram\Hydrator\JsonHydrator;
@@ -35,6 +37,7 @@ class Api
3537

3638
/**
3739
* Api constructor.
40+
*
3841
* @param Client|null $client
3942
* @param CacheManager|null $cacheManager
4043
*/
@@ -46,9 +49,10 @@ public function __construct(CacheManager $cacheManager = null, Client $client =
4649

4750
/**
4851
* @param integer $limit
52+
*
4953
* @return Hydrator\Component\Feed
5054
*
51-
* @throws CacheException
55+
* @throws InstagramCacheException
5256
* @throws InstagramException
5357
* @throws \GuzzleHttp\Exception\GuzzleException
5458
* @throws \Exception
@@ -61,7 +65,7 @@ public function getFeed($limit = 12)
6165

6266
if ($this->endCursor) {
6367
if (!$this->cacheManager instanceof CacheManager) {
64-
throw new CacheException('CacheManager object must be specified to use pagination');
68+
throw new InstagramCacheException('CacheManager object must be specified to use pagination');
6569
}
6670

6771
$feed = new JsonTransportFeed($this->client, $this->endCursor, $this->cacheManager);
@@ -93,4 +97,29 @@ public function setEndCursor($endCursor)
9397
{
9498
$this->endCursor = $endCursor;
9599
}
100+
101+
/**
102+
* @param $username
103+
* @param $password
104+
* @param Client|null $client
105+
*
106+
* @throws Exception\InstagramAuthException
107+
* @throws InstagramCacheException
108+
* @throws InstagramException
109+
* @throws \GuzzleHttp\Exception\GuzzleException
110+
*/
111+
public function login($username, $password, Client $client = null)
112+
{
113+
if (!$this->cacheManager instanceof CacheManager) {
114+
throw new InstagramCacheException('CacheManager is required with login');
115+
}
116+
117+
$login = new Login($client);
118+
$cookies = $login->execute($username, $password);
119+
120+
if ($cookies instanceof CookieJar) {
121+
$this->cacheManager->sessionName = $username;
122+
$this->cacheManager->setSession($username, $cookies);
123+
}
124+
}
96125
}

src/Instagram/Auth/Login.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace Instagram\Auth;
4+
5+
use GuzzleHttp\Client;
6+
use GuzzleHttp\Cookie\CookieJar;
7+
use Instagram\Exception\InstagramAuthException;
8+
use Instagram\Exception\InstagramException;
9+
use Instagram\Transport\TransportFeed;
10+
11+
class Login
12+
{
13+
/**
14+
* @var Client
15+
*/
16+
private $client;
17+
18+
/**
19+
* @param Client|null $client
20+
*/
21+
public function __construct(Client $client = null)
22+
{
23+
$this->client = $client ?: new Client();
24+
}
25+
26+
/**
27+
* @param $username
28+
* @param $password
29+
*
30+
* @return CookieJar
31+
*
32+
* @throws InstagramAuthException
33+
* @throws InstagramException
34+
* @throws \GuzzleHttp\Exception\GuzzleException
35+
*/
36+
public function execute($username, $password)
37+
{
38+
$query = $this->client->request('GET', TransportFeed::BASE_URL, [
39+
'headers' => [
40+
'user-agent' => TransportFeed::USER_AGENT
41+
]
42+
]);
43+
44+
$html = (string)$query->getBody();
45+
46+
preg_match('/<script type="text\/javascript">window\._sharedData\s?=(.+);<\/script>/', $html, $matches);
47+
48+
if (!isset($matches[1])) {
49+
throw new InstagramException('Unable to extract JSON data');
50+
}
51+
52+
$data = json_decode($matches[1]);
53+
54+
$cookieJar = new CookieJar();
55+
56+
$query = $this->client->request('POST', TransportFeed::AUTH_URL, [
57+
'form_params' => [
58+
'username' => $username,
59+
'password' => $password,
60+
],
61+
'headers' => [
62+
'cookie' => 'ig_cb=1; csrftoken=' . $data->config->csrf_token,
63+
'referer' => TransportFeed::BASE_URL,
64+
'x-csrftoken' => $data->config->csrf_token,
65+
'user-agent' => TransportFeed::USER_AGENT,
66+
],
67+
'cookies' => $cookieJar
68+
]);
69+
70+
if ($query->getStatusCode() !== 200) {
71+
throw new InstagramAuthException('Unknown error');
72+
} else {
73+
$response = json_decode((string)$query->getBody());
74+
if ($response->authenticated == true) {
75+
return $cookieJar;
76+
} else {
77+
throw new InstagramAuthException('Wrong login / password');
78+
}
79+
}
80+
}
81+
}

src/Instagram/Exception/CacheException.php

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Instagram\Exception;
4+
5+
class InstagramAuthException extends \Exception
6+
{
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Instagram\Exception;
4+
5+
class InstagramCacheException extends \Exception
6+
{
7+
}

src/Instagram/Hydrator/HtmlHydrator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function getHydratedData()
5858
$media->setComments($node->edge_media_to_comment->count);
5959
$media->setLikes($node->edge_liked_by->count);
6060

61-
$media->setLink(TransportFeed::INSTAGRAM_ENDPOINT . "p/{$node->shortcode}/");
61+
$media->setLink(TransportFeed::BASE_URL . "p/{$node->shortcode}/");
6262

6363
$media->setThumbnails($node->thumbnail_resources);
6464

0 commit comments

Comments
 (0)