cURL with cookies

Discussion in 'PHP' started by Riverofrhyme, Mar 5, 2009.

  1. #1
    On my forum hosted on someone else's server, I load a php file which is on my server. In that file, it loads a specific page, but it only returns the information I need when logged in. Using file_get_contents() loads the page as a guest, not using the cookies already set when you log in. I've tried cURL but that does the same. Is there any way that I can make cURL use the cookies that have already been set (well they're sessions) so it loads the page as if I am logged in (which I am). I can't grab the session data though since it's been set on a different domain. It basically needs to work like JavaScript AJAX, but it must use PHP.
     
    Riverofrhyme, Mar 5, 2009 IP
  2. gapz101

    gapz101 Well-Known Member

    Messages:
    524
    Likes Received:
    8
    Best Answers:
    2
    Trophy Points:
    150
    #2
    then use this:

    CURLOPT_COOKIEFILE
    CURLOPT_COOKIEJAR
     
    gapz101, Mar 5, 2009 IP
  3. Riverofrhyme

    Riverofrhyme Peon

    Messages:
    137
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #3
    it's sessions. but I don't have access to the name of the sessions or the content. Basically, I need it to use the sessions that are stored on my computer, instead of me inputting the cookies to use.
     
    Riverofrhyme, Mar 6, 2009 IP
  4. exodus

    exodus Well-Known Member

    Messages:
    1,900
    Likes Received:
    35
    Best Answers:
    0
    Trophy Points:
    165
    #4
    It is a bit complicated to explain, because it can get confusing. I don't think you understand. cUrl acts as a web browser itself. cUrl is not going to be able to access your browsers cookies for a certain websites. You will have to log in using cUrl and then cUrl will store the cookies and then be logged into the website. cUrl and your browser will get different session id's from the php software. It is like opening the forum in IE and logging into the website. Then opening firefox or chrome and expecting firefox/chrome to read the cookies from IE and have you automaticly logged into the forum. Which it does not do. You have to in firefox/chrome/cUrl themselves to log into the forum to set the cookies and be logged in.
     
    exodus, Mar 6, 2009 IP
  5. Riverofrhyme

    Riverofrhyme Peon

    Messages:
    137
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Ahh I see, that's.. ..annoying.

    In that case then, I will need to run a cURL function once to login to an account, and then run another cURL function to grab the page I need. Will the second cURL function run once the first one is complete, or will I need to use a callback function of some kind? How do I make it so it stores the cookies temporarily (when logging in) then grabs the page using those cookies, then deletes those cookies?
     
    Riverofrhyme, Mar 7, 2009 IP
  6. Kaizoku

    Kaizoku Well-Known Member

    Messages:
    1,261
    Likes Received:
    20
    Best Answers:
    1
    Trophy Points:
    105
    #6
    Kaizoku, Mar 7, 2009 IP
  7. exodus

    exodus Well-Known Member

    Messages:
    1,900
    Likes Received:
    35
    Best Answers:
    0
    Trophy Points:
    165
    #7
    You can run cUrl any amount of times you need in a linear fashion inside a script.
     
    exodus, Mar 7, 2009 IP
  8. Riverofrhyme

    Riverofrhyme Peon

    Messages:
    137
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #8
    Ok, I've been trying some stuff out. The first code below will log into the forum successfully using cURL, but the cURL function after it loads the forum page as a guest. THis means it's not using the cookies/sessions set during the login cURL. Any reason why?

    Test site: http://aio.zetabin.com/testpost.php

    testlogin.php
    <?php
    
    /**
     * ZetaBoards Login Check
     * 
     * File: ZBLogin Class (ZBLogin.php)
     * Author: Jeremy Privett on November 13, 2008
     * 
     * @category  ZBLogin
     * @package   ZBLogin
     * @copyright Copyright (c) 2008 Jeremy Privett ( http://www.jeremyprivett.com )
     */
     
    /** 
     * Class to attempt a crendential check against a ZetaBoards forum.
     * 
     * Usage:
     * 
     * <code>
     * $ZBLogin = new ZBLogin();
     * $result = $ZBLogin->setForumUrl("http://s1.zetaboards.com/OVTest")
     *                 ->setLoginInfo("TestUser", "TestPassword")
     *                 ->tryLogin();
     * 
     * if ( $result == false ) {
     *     $error = $ZBLogin->getError();
     *     echo "Could not login. Error received: {$error}";
     * }
     * else {
     *     echo "Login successful.";
     * }
     * </code>
     *
     * @category  ZBLogin
     * @package   ZBLogin
     * @copyright Copyright (c) 2008 Jeremy Privett ( http://www.jeremyprivett.com )
     */
    class ZBLogin
    {
        /**
         * Any error message that we may have.
         * 
         * @access private
         * @var    string
         */
        private $error    = "";
        
        /**
         * The forum URL to use. Do not add a trailing slash.
         *
         * @access private
         * @var    string
         */
        private $forumUrl = "";
        
        /**
         * The username to use. 
         *
         * @access private
         * @var    string
         */
        private $username = "";
        
        /**
         * The password to use. 
         *
         * @access private
         * @var    string
         */
        private $password = "";
        
        /**
         * Constructor takes the URL to the forum to attempt credential
         * checks against. Do not add a trailing slash.
         * 
         * @access public
         * @param  string $forumUrl
         * @return ZBLogin
         */
        public function __construct($forumUrl = "")
        {
            $this->forumUrl = $forumUrl;
        }
        
        /**
         * Set the forum URL to use. Do not add a trailing slash.
         * 
         * @access public
         * @param  string $forumUrl
         * @return ZBLogin
         */
        public function setForumUrl($forumUrl)
        {
            $this->forumUrl = $forumUrl;
            return $this;
        }
        
        /**
         * Set the username and password to use.
         * 
         * @access public
         * @param  string $username
         * @param  string $password
         * @return ZBLogin
         */
        public function setLoginInfo($username, $password)
        {
            $this->username = $username;
            $this->password = $password;
            return $this;
        }
        
        /**
         * Gets the last error message.
         * 
         * @access public
         * @return string
         */
        public function getError()
        {
            return $this->error;
        }
        
        /**
         * Attempt to login and return the result.
         * 
         * @access public
         * @return boolean
         */
        public function tryLogin()
        {
            return $this->doLogin();
        }
        
        /**
         * Uses cURL in order to try to login to the
         * ZetaBoard provided in $forumUrl with $username
         * and $password.
         * 
         * @access private
         * @return boolean
         */
        private function doLogin()
        {
            $c = curl_init();
            
            /**
             * HTTP POST data to {forumUrl}/login/log_in/
             */
    $ckfile = tempnam ("/tmp", "CURLCOOKIE");
            curl_setopt($c, CURLOPT_URL, "{$this->forumUrl}/login/log_in/");
    curl_setopt($c, CURLOPT_COOKIEJAR, $ckfile);
            curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($c, CURLOPT_HEADER, false);
            curl_setopt($c, CURLOPT_POST, true);
            
            /**
             * Sample Request Data: uname=Test&pw=test&cookie_on=1&anon_on=0
             */
            $data = array('uname' => $this->username, 'pw' => $this->password, 'cookie_on' => 0, 'anon_on' => 0);
            $data = http_build_query($data);
            
            curl_setopt($c, CURLOPT_POSTFIELDS, $data);
            $r = curl_exec($c);
            
            /**
             * From my tests with an HTTP request inspector, ZetaBoards takes
             * login information and immediately redirects the browser (302)
             * on success. It returns 200 with an error block on failure.
             */
            $httpCode = curl_getinfo($c, CURLINFO_HTTP_CODE);
            
            if ( $httpCode == "302" ) {
                $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,'http://s1.zetaboards.com/zbaio_reg/search/?c=2&month=3&year=2009&mid=481089');
    curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $content= curl_exec($ch);
    curl_close($ch);
    echo $content;
    return true;
            }
            else {
                /**
                 * Let's do a little page scraping to get the error that
                 * the ZetaBoard returned. We're looking for the contents
                 * of <dl class="notice error"></dl> so we can get the
                 * error block. Within that, we need to get the contents of
                 * <dd></dd> for the actual error string. We'll strip the
                 * tags off that string. Don't want any HTML in our error.
                 */
                $regex      = "/<dl class=\"notice error\">(.*?)<\/dl>/ms";
                $innerRegex = "/<dd>(.*?)<\/dd>/ms";
                
                if ( preg_match($regex, $r, $m) and preg_match($innerRegex, $m[1], $matches) ) {
                    $this->error = strip_tags($matches[1]);
                }
                else {
                    /**
                     * If we don't get an error message out of the above, it's
                     * usually because there were too many requests at once. Let's
                     * give them ZB's "wait a few seconds" message.
                     */
                    $this->error = "Please wait at least 3 seconds between each login attempt.";
                }
                
                return false;
            }
        }
    }
    PHP:
    testpost.php
    <?php
    include_once("testlogin.php");
    
    $ZBLogin = new ZBLogin();
    $result = $ZBLogin->setForumUrl("http://s1.zetaboards.com/zbaio_reg")
    ->setLoginInfo("Test", "testing")
    ->tryLogin();
    
    if ( $result == false ) {
    $error = $ZBLogin->getError();
    echo "Could not login. Error received: {$error}";
    }
    ?>
    PHP:
     
    Riverofrhyme, Mar 7, 2009 IP
  9. exodus

    exodus Well-Known Member

    Messages:
    1,900
    Likes Received:
    35
    Best Answers:
    0
    Trophy Points:
    165
    #9
    That class is to log into a 'ZetaBoards forum' is that the forum you want to login? Also, what is the code your using after that portion?
     
    exodus, Mar 7, 2009 IP
  10. Riverofrhyme

    Riverofrhyme Peon

    Messages:
    137
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #10
    Yes, it is a ZetaBoards forum I am logging into.

    In the testlogin.php code, it checks for a return status of 302 (ZetaBoards uses this redirect when logging in). If it gets a 302 status, it does the following:

    if ( $httpCode == "302" ) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL,'http://s1.zetaboards.com/zbaio_reg/search/?c=2&month=3&year=2009&mid=481089');
            curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $content= curl_exec($ch);
            curl_close($ch);
            echo $content;
            return true;
    }
    PHP:
    Unfortunately, it must not be reading the cookies set in the $ckfile file.
     
    Riverofrhyme, Mar 7, 2009 IP
  11. exodus

    exodus Well-Known Member

    Messages:
    1,900
    Likes Received:
    35
    Best Answers:
    0
    Trophy Points:
    165
    #11
    exodus, Mar 7, 2009 IP
  12. Riverofrhyme

    Riverofrhyme Peon

    Messages:
    137
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #12
    I think you missed this part :p :

    curl_setopt($c, CURLOPT_URL, "{$this->forumUrl}/login/log_in/");
     
    Riverofrhyme, Mar 7, 2009 IP