Question

I have been trying to make cURL login into pinterest.com for the last 17 hours straight, have tried countless and countless different ways just with cURL but it does not work at all.

My current code only goes to the page but the data is not posted, so it does not login just takes me to the login page.

This first code is using USERPWD which is where it takes me to the login page but it does not login.

error_reporting(E_ALL); 
ini_set("display_errors", 1); 

$url = "https://www.pinterest.com/login/";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // allow https verification if true
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // check common name and verify with host name
curl_setopt($ch, CURLOPT_SSLVERSION,3); // 
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "pin.pem"); // allow ssl cert direct comparison
curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE); // set new cookie session
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies.txt");
curl_setopt($ch, CURLOPT_USERPWD, "email:password");

curl_setopt($ch, CURLOPT_SSLVERSION,3);

// grab URL and pass it to the browser
curl_exec($ch);

// close cURL connection, save cookie file, free up system resources
curl_close($ch);

and if I switch it from CURLOPT_USERPWD to

curl_setopt($ch, CURLOPT_POSTFIELDS, 'username_or_email=$email&password=$password');

it just displays a blank page.

The pin.pem is the X.509 Certificate (PEM) file.

Any direction to make this work would be greatly appreciated it.

Edit

new code but leaves blank page and I got the output with a few arrays and displays this:

Array ( [url] => https://www.pinterest.com/login/ [content_type] => [http_code] => 0 [header_size] => 0 [request_size] => 0 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.036169 [namelookup_time] => 3.3E-5 [connect_time] => 0.036186 [pretransfer_time] => 0 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => -1 [upload_content_length] => -1 [starttransfer_time] => 0 [redirect_time] => 0 [certinfo] => Array ( ) [redirect_url] => ) 

error_reporting(E_ALL); 
ini_set("display_errors", 1); 

$email = 'email';
$password = 'password';

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://www.pinterest.com/login/');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSLVERSION,3); // 
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . 'pin.pem');
curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE); 
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username_or_email=$email&password=$password');
curl_setopt($ch, CURLOPT_SSLVERSION,3);

curl_exec($ch);

$output=@curl_exec($ch);
$info = @curl_getinfo($ch);

echo $output;
print_r($info);

curl_close($ch);
Was it helpful?

Solution

The Pinterest login process isn't quite that simple. They use a CSRF token which you must extract and send with your login, along with the username and password in the POST body.

Here is what an actual login request to Pinterest looks like, so you will need to emulate this with cURL.

POST /resource/UserSessionResource/create/ HTTP/1.1
Host: www.pinterest.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-CSRFToken: 2rjgN4Qv67pN4wX91kTr4eIkgF54CzJH
X-NEW-APP: 1
X-APP-VERSION: 737af79
X-Requested-With: XMLHttpRequest
Referer: https://www.pinterest.com/login/
Content-Length: 300
Cookie: csrftoken=2rjgN4Qv67pN4wX91kTr4eIkgF54CzJH; _pinterest_sess="aPgJnrIBzvSKLUY/4H5UocshliA47GkkGtHLQwo1H4IcQv58vrdazclonByOb4fWCzb3a3nycKjQzDc6SkCB9eBKoejaLiCjkKLk/QAFRn2x1pvHFlFM+1EoD01/yFxmeQKlvULYU9+qf4D6Mkj8A=="; _track_cm=1;
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

source_url=%2Flogin%2F&data=%7B%22options%22%3A%7B%22username_or_email%22%3A%22YOU%40YOUROMAIN.COM%22%2C%22password%22%3A%22YOURPASSWORD%22%7D%2C%22context%22%3A%7B%7D%7D&module_path=App()%3ELoginPage()%3ELogin()%3EButton(class_name%3Dprimary%2C+text%3DLog+In%2C+type%3Dsubmit%2C+size%3Dlarge)

The source_url data in the request is the POST body (urlencoded). Take note that username_or_email is your login (I put YOU%40YOURDOMAIN.COM) and password is the password.

What you will have to do is make a GET request to /login/ to establish a session and cookies in the cURL session. Then using the same cURL handle, you can switch to a POST request, set CURLOPT_POSTFIELDS with the data from the source_url...... line.

You will probably also need to set the headers X-CSRFToken, X-NEW-APP, X-APP-VERSION, and X-Requested-With to match the above (except you will need to figure out how to get the correct CSRF Token value).

Unfortunately I don't have the time right now to make a working example, the next paragraph may help. You will need to use your browser to help you debug some of the HTTP requests to figure out all the requests you may need to make to get all the relevant data for your request.

If you check out this answer it shows curl login with PHP and links to a number of useful other related answers with examples.

EDIT:

Here is a working example of using PHP and cURL to log in to Pinterest.

This code is a Pinterest PHP login example (works as of 2014-05-11]. You may ask yourself, can what I want to do be done with the API instead of this hackish code which could break at any time???

As you can see I parse the CSRF_Token out of the headers, you should probably do this for the APP-VERSION as well since it can update almost daily. Right now it's hard coded.

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

$username   = 'you@yoursite.com';  // your username
$password   = 'yourpassword';      // your password

// this is the http post data for logging in - username & password are substituted in later
$login_post     = array(
        'source_url' => '/login/',
        'data' => '{"options":{"username_or_email":"%s","password":"%s"},"context":{}}',
        'module_path' => 'App()>LoginPage()>Login()>Button(class_name=primary, text=Log In, type=submit, size=large',
);
$pinterest_url  = 'https://www.pinterest.com/';  // pinterest home url
$login_url      = $pinterest_url . 'login/';     // pinterest login page url
$login_post_url = $pinterest_url . 'resource/UserSessionResource/create/'; // pinterest login post url

// http headers to send with requests
$httpheaders    = array(
       'Connection: keep-alive',
       'Pragma: no-cache',
       'Cache-Control: no-cache',
       'Accept-Language: en-US,en;q=0.5',
);

// http headers to send when logging in
$login_header   = array(
        'X-NEW-APP: 1',
        'X-APP-VERSION: d2bb370',  // THIS WILL UPDATE FREQUENTLY, CHANGE IT!!!
        'X-Requested-With: XMLHttpRequest',
        'Accept: application/json, text/javascript, */*; q=0.01');

// ----------------------------------------------------------------------------
// request home page to establish cookies and a session, set curl options

$ch = curl_init($pinterest_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Iron/31.0.1700.0 Chrome/31.0.1700.0');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_STDERR, fopen('/tmp/debug.txt', 'w+'));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheaders);

$data = curl_exec($ch);

// ----------------------------------------------------------------------------

// parse the csrf token out of the cookies to set later when logging in
list($headers, $body) = explode("\r\n\r\n", $data, 2);

preg_match('/csrftoken=(.*?)[\b;\s]/i', $headers, $csrf_token);

// next request the login page
curl_setopt($ch, CURLOPT_URL, $login_url);
$data = curl_exec($ch);

// ----------------------------------------------------------------------------
// perform login post    

$login_header[] = 'X-CSRFToken: ' . $csrf_token[1];

$login_post['data'] = sprintf($login_post['data'], $username, $password);
$post               = http_build_query($login_post);

curl_setopt($ch, CURLOPT_URL, $login_post_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($httpheaders, $login_header));
curl_setopt($ch, CURLOPT_REFERER, $login_url);
curl_setopt($ch, CURLOPT_HEADER, 0);

$data = curl_exec($ch);

// check response and output status

if (curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
    echo "Error logging in.<br />";
    var_dump(curl_getinfo($ch));
} else {
    $response = json_decode($data, true);

    if ($response === null) {
        echo "Failed to decode JSON response.<br /><br />";
        var_dump($response);
    } else if ($response['resource_response']['error'] === null) {
        echo "Login successful, " . $response['resource_response']['data']['username'] . "<br /><br />";
        echo "You have {$response['resource_response']['data']['follower_count']} followers, are following {$response['resource_response']['data']['following_count']} users.  You have liked {$response['resource_response']['data']['like_count']} pins.";
    }
}

My output:

Login successful, drew010

You have 0 followers, are following 0 users. You have liked 0 pins.

OTHER TIPS

FYI, Pinterest has login rate limit so don't run this before every request.

Here is my Ruby implementation of the Pinterest login/session mechanism. Run this once a day to save the headers (including csrftoken). Then use the saved headers to do requests that are not (yet) supported by the api (like ads reports).

class PinterestHeadersScheduler

  include Sidekiq::Worker
  sidekiq_options queue: :recurring, retry: 0

  HOMEPAGE    = 'https://ads.pinterest.com/'
  LOGIN_URL   = "#{HOMEPAGE}login/"
  SESSION_URL = "#{HOMEPAGE}resource/UserSessionResource/create/"

  LOGIN_DATA = {
      source_url: '/login/',
      data: { options: { username_or_email: ENV['PI_USERNAME'], password: ENV['PI_PASSWORD'] }, context: {} }.to_json
  }

  HEADERS = {
      'Accept':           'application/json,text/html,image/webp,image/apng,*/*;q=0.8',
      'Origin':           'https://ads.pinterest.com',
      'Referer':          'https://ads.pinterest.com/',
      'User-Agent':       'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
      'Connection':       'keep-alive',
      'Cache-Control':    'no-cache',
      'Accept-Charset':   'utf-8;ISO-8859-1q=0.7,*;q=0.7',
      'Accept-Encoding':  'gzip, deflate',
      'Accept-Language':  'en-US,en;q=0.8'
  }

  SESSION_HEADERS = HEADERS.merge({
      'Accept':           'application/json',
      'Content-Type':     'application/x-www-form-urlencoded; charset=UTF-8',
      'X-Requested-With': 'XMLHttpRequest'
  })

  def perform
    login   = HTTParty.get(LOGIN_URL, { headers: HEADERS })
    cjar    = login.get_fields('Set-Cookie').each_with_object(HTTParty::CookieHash.new) { |cookie, jar| jar.add_cookies(cookie) }
    headers = SESSION_HEADERS.merge({ 'Cookie': cjar.to_cookie_string, 'X-CSRFToken': cjar[:csrftoken] })

    res     = HTTParty.post(SESSION_URL, { headers: headers, body: LOGIN_DATA.to_param })
    session = JSON.parse(ActiveSupport::Gzip.decompress(res.body))
    raise "login error #{session['resource_response']['error']}" if session['resource_response']['error']

    cjar = res.headers.get_fields('Set-Cookie').each_with_object(HTTParty::CookieHash.new) { |cookie, jar| jar.add_cookies(cookie) }
    save_session_headers(HEADERS.merge({ 'Cookie' => cjar.to_cookie_string }))
  end

  def save_session_headers(headers)
    # replace this with your cache/db
    Utils::RedisUtil.set(:pinterest_session_headers, headers.to_json)
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top