Closed chokies closed 5 years ago
Hello,
Issue is probably similar with this one: https://github.com/postaddictme/instagram-php-scraper/issues/365
Regards.
I managed to patch this myself. Change the login method in Instagram.php to the following and the login method will work again.
From what I can see Instagram no longer passes the CSRF token in the Set-Cookie header. Instead they output it as a json object in the response body. My method just parses the body to obtain the CSRF token.
/**
* @param bool $force
* @param bool $support_two_step_verification
*
* $support_two_step_verification true works only in cli mode - just run login in cli mode - save cookie to file and use in any mode
*
* @throws InstagramAuthException
* @throws InstagramException
*
* @return array
*/
public function login($force = false, $support_two_step_verification = false)
{
if ($this->sessionUsername == null || $this->sessionPassword == null) {
throw new InstagramAuthException("User credentials not provided");
}
$cachedString = static::$instanceCache->getItem($this->sessionUsername);
$session = $cachedString->get();
if ($force || !$this->isLoggedIn($session)) {
$response = Request::get(Endpoints::BASE_URL);
if ($response->code !== 200) {
throw new InstagramException('Response code is ' . $response->code . '. Body: ' . static::getErrorBody($response->body) . ' Something went wrong. Please report issue.');
}
preg_match('/"csrf_token":"(.*?)"/', $response->body, $match);
if(isset($match[1])) {
$csrfToken = $match[1];
}
$mid = $cookies['mid'];
$headers = ['cookie' => "csrftoken=$csrfToken; mid=$mid;",
'referer' => Endpoints::BASE_URL . '/',
'x-csrftoken' => $csrfToken,
];
$response = Request::post(Endpoints::LOGIN_URL, $headers,
['username' => $this->sessionUsername, 'password' => $this->sessionPassword]);
if ($response->code !== 200) {
if ($response->code === 400 && isset($response->body->message) && $response->body->message == 'checkpoint_required' && $support_two_step_verification) {
$response = $this->verifyTwoStep($response, $cookies);
} elseif ((is_string($response->code) || is_numeric($response->code)) && is_string($response->body)) {
throw new InstagramAuthException('Response code is ' . $response->code . '. Body: ' . $response->body . ' Something went wrong. Please report issue.');
} else {
throw new InstagramAuthException('Something went wrong. Please report issue.');
}
}
if (is_object($response->body)) {
if (!$response->body->authenticated) {
throw new InstagramAuthException('User credentials are wrong.');
}
}
$cookies = static::parseCookies($response->headers['Set-Cookie']);
$cookies['mid'] = $mid;
$cachedString->set($cookies);
static::$instanceCache->save($cachedString);
$this->userSession = $cookies;
} else {
$this->userSession = $session;
}
return $this->generateHeaders($this->userSession);
}
@developedsoftware,
$mid = $cookies['mid'];
Where is $cookies definded?
There is a line of code missing
$cookies = static::parseCookies($response->headers['Set-Cookie']);
Feel free to patch and commit.
@developedsoftware
"Undefined index: Set-Cookie"
Hmm perhaps $mid can just be taken out altogether then ? I didnt investigate what it actually did - just patched the csrf token being in the body. Will have to take another look and do another merge request.
array:13 [
0 => "HTTP/1.1 200 OK"
"Content-Type" => "text/html"
"X-Frame-Options" => "SAMEORIGIN"
"Cache-Control" => "private, no-cache, no-store, must-revalidate"
"Pragma" => "no-cache"
"Expires" => "Sat, 01 Jan 2000 00:00:00 GMT"
"Vary" => "Cookie, Accept-Language, Accept-Encoding"
"Content-Language" => "en"
"Content-Encoding" => "gzip"
"Date" => "Fri, 01 Jun 2018 10:59:02 GMT"
"Strict-Transport-Security" => "max-age=86400"
"Connection" => "keep-alive"
"Content-Length" => "5556"
]
Yeah looks like $mid is completely redundant - perhaps @raiym can confirm what it was originally used for?
This worked for me
public function login($force = false, $support_two_step_verification = false)
{
if ($this->sessionUsername == null || $this->sessionPassword == null) {
throw new InstagramAuthException("User credentials not provided");
}
$cachedString = static::$instanceCache->getItem($this->sessionUsername);
$session = $cachedString->get();
if ($force || !$this->isLoggedIn($session)) {
$response = Request::get(Endpoints::BASE_URL);
if ($response->code !== 200) {
throw new InstagramException('Response code is ' . $response->code . '. Body: ' . static::getErrorBody($response->body) . ' Something went wrong. Please report issue.');
}
preg_match('/"csrf_token":"(.*?)"/', $response->body, $match);
if(isset($match[1])) {
$csrfToken = $match[1];
}
$headers = ['cookie' => "csrftoken=$csrfToken;",
'referer' => Endpoints::BASE_URL . '/',
'x-csrftoken' => $csrfToken,
];
$response = Request::post(Endpoints::LOGIN_URL, $headers,
['username' => $this->sessionUsername, 'password' => $this->sessionPassword]);
$cookies = static::parseCookies($response->headers['Set-Cookie']);
$mid = $cookies['mid'];
if ($response->code !== 200) {
if ($response->code === 400 && isset($response->body->message) && $response->body->message == 'checkpoint_required' && $support_two_step_verification) {
$response = $this->verifyTwoStep($response, $cookies);
} elseif ((is_string($response->code) || is_numeric($response->code)) && is_string($response->body)) {
throw new InstagramAuthException('Response code is ' . $response->code . '. Body: ' . $response->body . ' Something went wrong. Please report issue.');
} else {
throw new InstagramAuthException('Something went wrong. Please report issue.');
}
}
if (is_object($response->body)) {
if (!$response->body->authenticated) {
throw new InstagramAuthException('User credentials are wrong.');
}
}
$cookies = static::parseCookies($response->headers['Set-Cookie']);
$cookies['mid'] = $mid;
$cachedString->set($cookies);
static::$instanceCache->save($cachedString);
$this->userSession = $cookies;
} else {
$this->userSession = $session;
}
return $this->generateHeaders($this->userSession);
}
@fearrr Still it's giving error on login.
Have you updated to the latest version - it works fine for me.
Hi @developedsoftware ,
Yes, I already updated file( Instagram.php ) since 3days back It works but after a day it gives the same error as they giving before and my Instagram account saying suspicious login attempt again and again.
Thank You, M Zubair Sultan
Try another server / IP address. Your server is probably black listed, hence it not working.
Why blacklisted?? I have only one server or I will use the proxy? If Proxy then can you tell me how to use proxy server?
I cant answer that - maybe too many requests. Instagram decides what gets blocked or not. The suspicous login attempt will render all calls using this code useless. So if you can get around that (maybe using a proxy) then you should be OK. The actual code works fine.
Info on using a proxy and setting it up can be found here https://github.com/postaddictme/instagram-php-scraper
Ok great, Thanks, I will try by using proxies
im getting this error now when tryingto call login(). i have revalidated the instagram account already (entering the code from email/sms) and now i get this.
[code] => 200 [raw_body] => {"errors": {"error": ["Sorry, there was a problem with your request."]}, "status": "ok", "error_type": "generic_request_error"} [body] => stdClass Object ( [errors] => stdClass Object ( [error] => Array ( [0] => Sorry, there was a problem with your request. )