PHP cURL not working but python request session is working

Viewed 238

I want to write PHP for login in one website and this is my code:

    $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://www.daigger.com/account/access?redirect=%2f');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

        curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
            curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
            curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');

        $headers = array();
        
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            echo 'Error:' . curl_error($ch);
        }
        curl_close($ch);

        preg_match('/RequestVerificationToken\"\s*type=\"hidden\"\s*value=\"(.*?)\"/', $result, $matches);
        $token = $matches[1];


        $ch = curl_init();
        $post = '__RequestVerificationToken='. $token .'&SignIn.Email=' . urlencode ( $username ) . '&SignIn.Password=' . urlencode ( $password ) . '&SignIn.Password-clone=' . urlencode ( $password ) . '&SignIn.RememberMe=false';
            
        curl_setopt($ch, CURLOPT_URL, 'https://www.daigger.com/account/access?redirect=%2F');
    



  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  curl_setopt($ch, CURLOPT_TIMEOUT, 0);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

        curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_VERBOSE, true);
            curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
            curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');

        $headers = array();
        $headers[] = 'content-length: '.strlen($post);
        $headers[] = 'content-type:  application/x-www-form-urlencoded';

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $page = curl_exec($ch);
        print_r($page);
        if (curl_errno($ch)) {
            echo 'Error:' . curl_error($ch);
        }

        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($page, 0, $header_size);
        $body = substr($page, $header_size);
print_r($body);
        curl_close($ch);

This returns me Error:SSL read: errno -5961-bash-4.1

and then I use the same logic just in the python-requests:

import requests
import re


s = requests.Session()
url1 = "https://www.daigger.com/account/access?redirect=%2f"
res = s.get(url1)
output = re.search('RequestVerificationToken\"\s*type=\"hidden\"\s*value=\"(.*?)\"', res.text)
x = output[1]


url = "https://www.daigger.com/account/access?redirect=%2F"
payload = "__RequestVerificationToken=" + x + "&SignIn.Email=xxxxxxxxxxx&SignIn.Password=xxxxxx&SignIn.Password-clone=xxxxxxx&SignIn.RememberMe=false"
headers = {
  'content-length': str(len(payload)),
  'content-type': 'application/x-www-form-urlencoded',
}

response = s.post(url, headers=headers, data=payload)
print(response.text)

and this works, so the logic is the same, I tested this logic in python, and it's working but I need it to work in PHP, any help, what I'm missing in PHP?

2 Answers

First of all, you don't need to set most of the curl options like

CURLOPT_CUSTOMREQUEST
CURLOPT_ENCODING
CURLOPT_HTTPHEADER
CURLOPT_HTTP_VERSION
CURLOPT_MAXREDIRS
CURLOPT_HEADER
CURLOPT_VERBOSE

To make a login request by fetching the RequestVerificationToken from first curl request, we need to set the User Agent so that the server can drop/create a Session cookie which we're storing in-memory by setting following curl options

curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '');
curl_setopt($ch, CURLOPT_COOKIEFILE, '');

in the first curl request and this cookie session will persist for next requests until we don't close the curl handle

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.daigger.com/account/access?redirect=%2f');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/32.0.1700.107 Chrome/32.0.1700.107 Safari/537.36');
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '');
curl_setopt($ch, CURLOPT_COOKIEFILE, '');

$result = curl_exec($ch);
$info = curl_getinfo($ch);
if (curl_errno($ch)) {
    die('Error:' . curl_error($ch));
}

preg_match('/RequestVerificationToken\"\s*type=\"hidden\"\s*value=\"(.*?)\"/', $result, $matches);
$token = $matches[1];

$post = '__RequestVerificationToken='. $token .'&SignIn.Email=' . urlencode ( $username ) . '&SignIn.Password=' . urlencode ( $password ) . '&SignIn.Password-clone=' . urlencode ( $password ) . '&SignIn.RememberMe=false';

curl_setopt($ch, CURLOPT_URL, 'https://www.daigger.com/account/access?redirect=%2F');
curl_setopt($ch, CURLOPT_TIMEOUT, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

$page = curl_exec($ch);
$info = curl_getinfo($ch);
if (curl_errno($ch)) {
    die('Error:' . curl_error($ch));
}
curl_close($ch);
// Logged-in response
print_r($page);

I've tried this one myself and it's working for me.

Unless you specifically need it, I'm not sure why anyone would subject themselves to cURL. And you're making things even worse by setting all sorts of options you don't need. Instead, you should use a proper HTTP client library such as Guzzle.

Failing that, use of file_get_contents is much easier, especially for simple GET requests.

$url = "https://www.daigger.com/account/access?redirect=%2f";

// make the GET request
$result = file_get_contents($url);

// I didn't check this but parsing HTML with a regular expression
// is a BAD IDEA. DON'T DO IT
preg_match('/RequestVerificationToken\"\s*type=\"hidden\"\s*value=\"(.*?)\"/', $result, $matches);
$token = $matches[1];

// get the cookies
$cookies = [];
foreach($http_response_header as $head) {
    if(preg_match("/^Set-Cookie:\s*([^=]+)=([^;]+);(.+)$/", $head, $parts))
        $cookies[] = urlencode($parts[1]) . "=" . urlencode($parts[2]);
    }
}

// set the options for the POST request, a little more complicated than GET

$headers = [
    "Content-Type: application/x-www-form-urlencoded",
    "Cookies: " . implode(";", $cookies);
];
$headers = implode("\r\n", $headers);

// there are tools for building POST data strings,
// don't try to make them yourself, it's another bad idea
$postdata = http_build_query([
    "__RequestVerificationToken" => $token,
    "SignIn.Email" => $username,
    "SignIn.Password" => $password,
    "SignIn.Password-clone" => $password,
    "SignIn.RememberMe" => "false",
]);
$opts = [
    "http" => [
        "method"  => "POST",
        "header"  => $headers,
        "content" => $postdata,
    ]
];
$context  = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
Related