Pinterest login with PHP and cURL not working

前端 未结 2 1547
说谎
说谎 2021-01-15 17:56

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 wor

相关标签:
2条回答
  • 2021-01-15 18:17

    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
    
    0 讨论(0)
  • 2021-01-15 18:23

    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.

    0 讨论(0)
提交回复
热议问题