12

I have to send information to an external website using cURL. I set up Guzzle on my Laravel application. I have the basics set up, but according to the documentation of the website, there is an action that's required for the username and password. How can I pass the 'action' along with the credentials needed to log in and get access?

The website states:

curl [-k] –dump-header <header_file> -F “action=login” -F “username=<username>” -F “password=<password>” https://<website_URL>

My controller:

    $client = new \GuzzleHttp\Client();

    $response = $client->get('http://website.com/page/login/', array(
        'auth' => array('username', 'password')
    ));

    $xml = $response;
    echo $xml;

The website will load on the echo, but it will only pull up the login screen. I need those credentials to bypass the login screen (with a successful login) to get to the portion of information I need for cURL.

TRiG
  • 10,148
  • 7
  • 57
  • 107
Lynx
  • 1,462
  • 5
  • 32
  • 59

3 Answers3

13

curl -F submits a POST request instead of a GET request. So you'll need to modify your code accordingly, something like

$client = new \GuzzleHttp\Client();

$response = $client->post('http://website.com/page/login/', [
    'body' => [
        'username' => $username,
        'password' => $password,
        'action' => 'login'
    ],
    'cookies' => true
]
);

$xml = $response;
echo $xml;

See http://guzzle.readthedocs.org/en/latest/quickstart.html#post-requests, http://curl.haxx.se/docs/manpage.html#-F

Edit:

Just add ['cookies' => true] to requests in order to use the auth cookie associated with this GuzzleHttp\Client(). http://guzzle.readthedocs.org/en/latest/clients.html#cookies

$response2 = $client->get('http://website.com/otherpage/', ['cookies' => true]);
Jeremiah Winsley
  • 2,537
  • 18
  • 30
  • Using what you suggest I still get only the login page. Not sure what else I can try. – Lynx Aug 04 '14 at 15:05
  • Just to be sure, you can successfully perform a cURL request against the url with the given command, correct? – Jeremiah Winsley Aug 04 '14 at 16:01
  • I think so, when I echo the $xml variable the page will come up but only to the login screen. It needs to bring up the page but with a successful login. Then I can continue with what I need to do which is send over an xml file – Lynx Aug 04 '14 at 16:18
  • Sorry, I meant the command in your post. `curl -F "action=login" -F "username=" -F "password=" http://website.com/page/login/` Does that produce the login page or the correct page? – Jeremiah Winsley Aug 04 '14 at 16:29
  • Yeah, I had to download it and test it on my command prompt. Yeah, it gives me an error stating that the system cannot find the file specified so that must be the problem. – Lynx Aug 04 '14 at 16:50
  • I just fixed a missing bracket in my code. Can you give it a try now? – Jeremiah Winsley Aug 04 '14 at 17:02
  • I caught that when I copied the code. That didn't fix it either. I was able to get a response from my cmd line. I removed the
    section and got the same response as I did from the PHP side. I am not sure what needs to go in the
    – Lynx Aug 04 '14 at 17:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58628/discussion-between-jeremiah-winsley-and-lynx). – Jeremiah Winsley Aug 04 '14 at 17:11
  • Now that you got a xml response say "0" how can I get that in an array format? – Roydon D' Souza Jan 10 '16 at 21:16
  • 1
    @RoydonD'Souza Take a look at http://stackoverflow.com/a/6578969 and http://stackoverflow.com/a/3577662 – Jeremiah Winsley Jan 11 '16 at 15:25
  • @JeremiahWinsley Thanks a lot. The first link was helpful in my case. – Roydon D' Souza Jan 13 '16 at 12:32
12

I was having trouble getting @JeremiahWinsley's answer to work on newer version of Guzzle so I've updated their code to work as of Guzzle 5.x.

Three major changes are required

  • Using form_params instead of body to prevent the error "Passing in the "body" request option as an array to send a POST request has been deprecated."
  • Changing the cookies to use the CookieJar object
  • Use ->getBody()->getContents() to get the body of the request

Here is the updated code:

$client = new \GuzzleHttp\Client();
$cookieJar = new \GuzzleHttp\Cookie\CookieJar();

$response = $client->post('http://website.com/page/login/', [
    'form_params' => [
        'username' => $username,
        'password' => $password,
        'action' => 'login'
    ],
    'cookies' => $cookieJar
]
);

$xml = $response->getBody()->getContents();
echo $xml;

And to continue using cookies in future requests, pass in the cookieJar to the request:

$response2 = $client->get('http://website.com/otherpage/', ['cookies' => $cookieJar]);
Samsquanch
  • 8,866
  • 12
  • 50
  • 89
9

I was having trouble getting @JeremiahWinsley's and @Samsquanch's answer to work on newer version of Guzzle. So I've updated the code to work as of Guzzle 6.x.

Guzzle 6.x. documents: http://docs.guzzlephp.org/en/stable/index.html

Here is the updated code:

use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;

try {
        $client = new Client();
        $cookieJar = new CookieJar();

        $response = $client->request('POST', 'http://website.com/page/login/', [
            'form_params' => [
                'username' => 'test@example.com',
                'password' => '123456'
            ],
            'cookies' => $cookieJar
        ]);

        $response2 = $client->request('GET', 'http://website.com/otherpage/', [
            'cookies' => $cookieJar
        ]);

        if ($response2->getStatusCode() == 200) {
            return $response2->getBody()->getContents();
        } else {
            return "Oops!";
        }
    } catch (\Exception $exception) {
        return 'Caught exception: ', $exception->getMessage();
    }
Md Rasel Ahmed
  • 1,025
  • 9
  • 12