1

As of the 21st October 2019 Instagram prevented you from creating and managing your clients from within Instagram and everything is now managed through Facebook Developer, no real issue with that...

In my instance all that is required is to show a single user profile images. I got this working fairly quickly, however the Access Token just expires every 2 hours, then I need to re-authorise it again... This was never an issue before... You authorised once and it would just work.

Take this working code:

function fetchData($url){
  $inst = curl_init($url);
  curl_setopt($inst, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($inst, CURLOPT_SSL_VERIFYHOST, 0);
  curl_setopt($inst, CURLOPT_SSL_VERIFYPEER, 0);
  $output = curl_exec($inst);
  curl_close($inst);

  return $output;
}

$insta_access_token = 'MY_ACCESS_TOKEN';
$insta_count = '6';

$instagram_result = fetchData("https://graph.instagram.com/me/media?fields=id,username,media_url&access_token={$insta_access_token}&count={$insta_count}");
$instagram_result = json_decode($instagram_result);
print_r($instagram_result);

This works fine until the access token expires.

I have seen other tricks around not using the API at all located here: How can I get a user's media from Instagram without authenticating as a user?

This uses PHP to extract profile contents and is the only viable solution from my research to display a basic image gallery from a single use profile:

$html = file_get_contents('https://instagram.com/apple/');
preg_match('/_sharedData = ({.*);<\/script>/', $html, $matches);
$profile_data = json_decode($matches[1])->entry_data->ProfilePage[0]->graphql->user;

Am I missing something or is there no way to keep a valid access token running once authenticated once for basic image display?

Cheers.

Nick Howarth
  • 511
  • 4
  • 21
  • You probably want a Refresh Token https://tools.ietf.org/html/rfc6749#section-1.5 – delboy1978uk Nov 14 '19 at 10:52
  • @delboy1978uk unfortunately Instagram do not allow you to do this :( – Nick Howarth Nov 14 '19 at 11:03
  • in that case try and catch and just get a new token and make your call again :-| – delboy1978uk Nov 14 '19 at 11:22
  • @delboy1978uk only issue is that you cannot automate it, a user physically seems to have to click authorise... very frustrating. – Nick Howarth Nov 14 '19 at 11:57
  • that should only happen once! allow this app permission to blah bla blah, click yes, approved! then you only need log in to the 3rd party site (FB, instagram, whatever) if you dont havce the cookie and aren't logged in – delboy1978uk Nov 14 '19 at 12:46
  • @delboy1978uk if the user needed to login and authenticate their account that would be fine, but it is just a stand alone feed showing a single user profile accounts media, so any user visiting shouldn't need to do authenticate themselves to view if you get me? before this update all you did was authenticate your app once for basic usage and that was that. – Nick Howarth Nov 14 '19 at 13:24
  • I think possibly your client is using the wrong grant. I take it you arent using `client_credentials` grant? That's the one for machine to machine without user intervention – delboy1978uk Nov 14 '19 at 13:32
  • When I try client_credentials as the grant_type just throws a {"error_type": "OAuthException", "code": 400, "error_message": "Invalid grant_type"} – Nick Howarth Nov 14 '19 at 14:59
  • Double check the API client you created in Instagram has the correct grant type, if not, delete and create a new one. Then, follow the instructions at the bottom section of this page https://www.instagram.com/developer/authentication/ – delboy1978uk Nov 14 '19 at 16:46
  • Did you find a solution to this? I'm having exactly the same issue as you're having. – Steve Holland Dec 03 '19 at 16:25
  • 1
    @SteveHolland the below answer will give you an access token for slightly longer but will expire, the only way would be to write some code to re-authenticate and re-generate the access token on some form of cron job, I haven't got round to this yet I am afraid. Seems needlessly excessive for basic usage. The file_get_contents() method above in my original question is a cheeky workaround for now. – Nick Howarth Dec 04 '19 at 10:47
  • How did you get the new short-live token having the old access token in the first place? – lvil Dec 23 '19 at 11:14

2 Answers2

0

All what you need is to extend your access token duration by making a GET request to this endpoint (long lived access token is valuable for 60 days from what i know)

url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&%20client_id='Your_App_Id'&client_secret='Your_App_secret'&fb_exchange_token='Your_Short_Lived_Access_token''

Hope this is what you were looking for =)

0
 require_once __DIR__ . '/vendor/autoload.php';

// facebook credentials array
$creds = array(
    'app_id' => FACEBOOK_APP_ID,
    'app_secret' => FACEBOOK_APP_SECRET,
    'default_graph_version' => 'v3.2',
    'persistent_data_handler' => 'session'
);

// create facebook object
$facebook = new Facebook\Facebook( $creds );

// helper
$helper = $facebook->getRedirectLoginHelper();

// oauth object
$oAuth2Client = $facebook->getOAuth2Client();

if ( isset( $_GET['code'] ) ) { // get access token
    try {
        $accessToken = $helper->getAccessToken();
    } catch ( Facebook\Exceptions\FacebookResponseException $e ) { // graph error
        echo 'Graph returned an error ' . $e->getMessage;
    } catch ( Facebook\Exceptions\FacebookSDKException $e ) { // validation error
        echo 'Facebook SDK returned an error ' . $e->getMessage;
    }

    if ( !$accessToken->isLongLived() ) { // exchange short for long
        try {
            $accessToken = $oAuth2Client->getLongLivedAccessToken( $accessToken );
        } catch ( Facebook\Exceptions\FacebookSDKException $e ) {
            echo 'Error getting long lived access token ' . $e->getMessage();
        }
    }


    $accessToken = (string) $accessToken;
  • Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation](https://meta.stackexchange.com/q/114762/349538) would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you’ve made. – helvete Dec 17 '21 at 12:58