Instagram login programmatically

It looks like you were headed in the right direction, in your example, it seems that you get an authenticated response but a consequent request to an authenticated page does not work as expected.

I suspect that instagram is actively preventing this by running a check with an Ajax call or something similar.

As an alternative you can look at something like zombie.js.

This is a headless virtual browser where you can visit pages and interact with the elements on it, but you cant view them.

A simple example using zombie.js is as follows:

var Browser = require('zombie');
var browser = Browser.create();

browser.visit('https://instagram.com/', function() {
  browser.wait(10000, function(){
    browser.fill('input[name="username"]', 'myusername');
    browser.fill('input[type="password"]', 'mypasswd');
    browser.pressButton('Log in', function() {
      browser.visit('https://instagram.com/accounts/edit/', function() {
        console.log(browser.html());
      });
    });

  });

});

Hope it helps.


You can use classic login form with 'force_classic_login' parameter.

<?php
    $username = "username";
    $password = "password";
    $useragent = "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13";
    $cookie=$username.".txt";

    $url="https://instagram.com/accounts/login/?force_classic_login";

    $ch  = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/".$cookie);
    curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/".$cookie);
    curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

    $page = curl_exec($ch);

    // try to find the actual login form
    if (!preg_match('/<form method="POST" id="login-form" class="adjacent".*?<\/form>/is', $page, $form)) {
        throw Instagram_Manager('Failed to find log in form!');
    }

    $form = $form[0];

    // find the action of the login form
    if (!preg_match('/action="([^"]+)"/i', $form, $action)) {
        throw Instagram_Manager('Failed to find login form url');
    }

    $url2 = $action[1]; // this is our new post url
    // find all hidden fields which we need to send with our login, this includes security tokens
    $count = preg_match_all('/<input type="hidden"\s*name="([^"]*)"\s*value="([^"]*)"/i', $form, $hiddenFields);

    $postFields = array();

    // turn the hidden fields into an array
    for ($i = 0; $i < $count; ++$i) {
        $postFields[$hiddenFields[1][$i]] = $hiddenFields[2][$i];
    }

    // add our login values
    $postFields['username'] = $username;
    $postFields['password'] = $password;

    $post = '';

    // convert to string, this won't work as an array, form will not accept multipart/form-data, only application/x-www-form-urlencoded
    foreach($postFields as $key => $value) {
        $post .= $key . '=' . urlencode($value) . '&';
    }

    $post = substr($post, 0, -1);

    // set additional curl options using our previous options
    curl_setopt($ch, CURLOPT_URL, "https://instagram.com/".$url2);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
   $page = curl_exec($ch);

    // connect to profile edit page
    $url="https://instagram.com/accounts/edit/";
    curl_setopt($ch, CURLOPT_URL, $url);
    echo curl_exec($ch);    
?>

My great respect to @Fatih Kısa for his code, very good job. I have tried this code, but for now it doesn't work, probably, because of some Instagram server-side changes. I have played 2 days with his code and force it to work with my small changes. Very important part of this code is that Instagram accepts only post form with curl referrer which contains the cookies data (csrftoken and mid). Also important part is that you must use https://www.instagram.com/accounts/login/?force_classic_login, only with WWW and to remove after cookies creation the strings about curl info:

#Netscape HTTP Cookie File

#http://curl.haxx.se/docs/http-cookies.html

#This file was generated by libcurl! Edit at your own risk.

Here is working code, enjoy!

$username = "yourname";
$password = "yourpass";
$useragent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/50.0.2661.102 Chrome/50.0.2661.102 Safari/537.36";
$cookie=$username.".txt";

@unlink(dirname(__FILE__)."/".$cookie);

$url="https://www.instagram.com/accounts/login/?force_classic_login";

$ch  = curl_init();        

$arrSetHeaders = array(
    "User-Agent: $useragent",
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language: en-US,en;q=0.5',
    'Accept-Encoding: deflate, br',
    'Connection: keep-alive',
    'cache-control: max-age=0',
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $arrSetHeaders);         
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

$page = curl_exec($ch);
curl_close($ch);          

// try to find the actual login form
if (!preg_match('/<form data-encrypt method="POST" id="login-form" class="adjacent".*?<\/form>/is', $page, $form)) {
    die('Failed to find log in form!');
}

$form = $form[0];

// find the action of the login form
if (!preg_match('/action="([^"]+)"/i', $form, $action)) {
    die('Failed to find login form url');
}

$url2 = $action[1]; // this is our new post url
// find all hidden fields which we need to send with our login, this includes security tokens
$count = preg_match_all('/<input type="hidden"\s*name="([^"]*)"\s*value="([^"]*)"/i', $form, $hiddenFields);

$postFields = array();

// turn the hidden fields into an array
for ($i = 0; $i < $count; ++$i) {
    $postFields[$hiddenFields[1][$i]] = $hiddenFields[2][$i];
}

// add our login values
$postFields['username'] = $username;
$postFields['password'] = $password;   

$post = '';

// convert to string, this won't work as an array, form will not accept multipart/form-data, only application/x-www-form-urlencoded
foreach($postFields as $key => $value) {
    $post .= $key . '=' . urlencode($value) . '&';
}

$post = substr($post, 0, -1);   

preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $page, $matches);

$cookieFileContent = '';

foreach($matches[1] as $item) 
{
    $cookieFileContent .= "$item; ";
}

$cookieFileContent = rtrim($cookieFileContent, '; ');
$cookieFileContent = str_replace('sessionid=; ', '', $cookieFileContent);

$oldContent = file_get_contents(dirname(__FILE__)."/".$cookie);
$oldContArr = explode("\n", $oldContent);

if(count($oldContArr))
{
    foreach($oldContArr as $k => $line)
    {
        if(strstr($line, '# '))
        {
            unset($oldContArr[$k]);
        }
    }

    $newContent = implode("\n", $oldContArr);
    $newContent = trim($newContent, "\n");

    file_put_contents(
        dirname(__FILE__)."/".$cookie,
        $newContent
    );    
}

$arrSetHeaders = array(
    'origin: https://www.instagram.com',
    'authority: www.instagram.com',
    'upgrade-insecure-requests: 1',
    'Host: www.instagram.com',
    "User-Agent: $useragent",
    'content-type: application/x-www-form-urlencoded',
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language: en-US,en;q=0.5',
    'Accept-Encoding: deflate, br',
    "Referer: $url",
    "Cookie: $cookieFileContent",
    'Connection: keep-alive',
    'cache-control: max-age=0',
);

$ch  = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/".$cookie);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $arrSetHeaders);     
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);        

sleep(5);
$page = curl_exec($ch);


preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $page, $matches);
$cookies = array();
foreach($matches[1] as $item) {
    parse_str($item, $cookie1);
    $cookies = array_merge($cookies, $cookie1);
}
var_dump($page);      

curl_close($ch);