postaddictme / instagram-php-scraper

Get account information, photos, videos, stories and comments.
https://packagist.org/packages/raiym/instagram-php-scraper
MIT License
3.09k stars 800 forks source link

cant login anymore #368

Closed chokies closed 5 years ago

chokies commented 6 years ago

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. )

            )

        [status] => ok
        [error_type] => generic_request_error
    )

[headers] => Array
sfatfarma commented 6 years ago

Hello,

Issue is probably similar with this one: https://github.com/postaddictme/instagram-php-scraper/issues/365

Regards.

developedsoftware commented 6 years ago

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);
}
fearrr commented 6 years ago

@developedsoftware,

$mid = $cookies['mid']; 

Where is $cookies definded?

developedsoftware commented 6 years ago

There is a line of code missing

$cookies = static::parseCookies($response->headers['Set-Cookie']);

Feel free to patch and commit.

fearrr commented 6 years ago

@developedsoftware "Undefined index: Set-Cookie"

developedsoftware commented 6 years ago

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.

fearrr commented 6 years ago
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"
]
developedsoftware commented 6 years ago

Yeah looks like $mid is completely redundant - perhaps @raiym can confirm what it was originally used for?

fearrr commented 6 years ago

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);
    }
zubairsultan786 commented 6 years ago

@fearrr Still it's giving error on login.

developedsoftware commented 6 years ago

Have you updated to the latest version - it works fine for me.

zubairsultan786 commented 6 years ago

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

developedsoftware commented 6 years ago

Try another server / IP address. Your server is probably black listed, hence it not working.

zubairsultan786 commented 6 years ago

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?

developedsoftware commented 6 years ago

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

zubairsultan786 commented 6 years ago

Ok great, Thanks, I will try by using proxies