2

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 Answers2

1

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.

Haridarshan
  • 1,898
  • 1
  • 23
  • 38
  • this code does not give an error like before but also returns page HTML as unlogged user –  May 27 '21 at 17:29
  • Why will it work? What have you changed? Add some explanation to your answer to make it more useful. – miken32 May 27 '21 at 17:55
  • @miken32 I thought it will work because I've tried to make curl handle persistent by initialising curl handle only once and using it again to make the 2nd request like OP has done in python using `Session` Object – Haridarshan May 27 '21 at 19:27
  • You should edit your question to include an explanation. Blocks of code are not useful, especially to future visitors to the question. – miken32 May 27 '21 at 19:31
  • Also worth noting that you can just set `curl_setopt($ch, CURLOPT_COOKIEFILE, "");` to enable in-memory cookie storage for the life of the handle. No need to save to a file or set `CURLOPT_COOKIEJAR`. – miken32 May 27 '21 at 19:31
  • @miken32 agree about an explanation which I did and thanks for the suggestion of `in-memory` cookie storage. I've tried with your code but it's returning `500 Internal Server Error` – Haridarshan May 27 '21 at 20:20
0

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);
miken32
  • 42,008
  • 16
  • 111
  • 154