I'm trying to make a curl request to my laravel server, in that request I have to check whether the user of my laravel application is logged in or not. I use this code:
$transferAmount = 200;
//set POST variables
$url = URL::route('post-spend-partner');
$fields = array(
'transferAmount' => urlencode($transferAmount),
'cancelUrl' => urlencode(URL::route('get-return-page-example')),
'returnUrl' => urlencode(URL::route('get-return-page-example')),
);
// New Connection
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_URL, $url);
curl_exec($ch);
curl_close($ch);
In the requested url I'm just checking if I'm logged in or not, but it always returns false:
public function postSpendPartner() {
echo "Authenticated? " . (Auth::check() ? 'Yes' : 'No');
}
I know for sure that I'm logged in, if I try the exact same thing with Ajax it completely works!
Does anyone know what I could try, to solve this problem?
Best regards!
Fabrice
Some facts: HTTP is stateless. Session IDs need to be passed to the server in order to continue the session. Session IDs are (most of the time) stored in cookies. Cookies are included in the request.
Using a cookiejar could indeed be one possible solution. The fact that it works using Ajax, and not by re-submitting the request from your server might be because of the session-verification mechanism on the server: Some session implementations lock session IDs to the initial IP address. If the contents of your cookiejar file check out, that might be the culprit.
That aside: re-submitting the request via Curl from your server is a severe codesmell to me. A proper solution would to implement something such as OAuth.
Try sending your cookies as a header with your curl request.
// ...
$cookie_header = "Cookie:";
$headers = [];
foreach($_COOKIE as $key => $val) {
// Do sanitize cookie values
$cookie_header .= " ".$key."=".$value.";";
}
$headers[] = $cookie_header;
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
// ...
You could filter out unnecessary cookie values from $cookie_header.
Related
Im a newbie im trying to get a script to trigger another script with Curl in PHP but it dosent seem to be sending the paramaters.
Is there a seperate function to append parameters?
<?php
$time = time();
$message = "hello world";
$urlmessage = urlencode( $message );
$ch = curl_init("http://mysite.php?message=$urlmessage&time=$time");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
?>
Could anyone point me in the right direction??
The accepted answer is good for POST, but what if OP wanted specifically to GET? Some REST APIs specify the http method and often it's no good POSTing when you should be GETting.
Here is a fragment of code that does GET with some params:
$endpoint = 'http://example.com/endpoint';
$params = array('foo' => 'bar');
$url = $endpoint . '?' . http_build_query($params);
curl_setopt($ch, CURLOPT_URL, $url);
This will cause your request to be made with GET to http://example.com/endpoint?foo=bar. This is the default http method, unless you set it to something else like POST with curl_setopt($ch, CURLOPT_POST, true) - so don't do that if you specifically need to GET.
If you need to use one of the other http methods (DELETE or PUT for example) then use curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method). This also works for GET and POST.
You need curl_setopt() along with the CURLOPT_POSTFIELDS param.
That'll POST the given params to the target page.
curl_setopt($ch, CURLOPT_POSTFIELDS, 'foo=1&bar=2&baz=3');
PS: also check http_build_query() which is handy when sending many variables.
you need set CURLOPT_POST as true and CURLOPT_POSTFIELDS => parameters
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
a suggestion,set 'CURLOPT_RETURNTRANSFER', as true to return the transfer as a string of the return value of curl_exec($ch) instead of outputting it out directly
Here is A Simple Solution for this.
$mobile_number = $_POST['mobile_number'];
$sessionid = $_POST['session_id'];
CURLOPT_URL => 'https://xxyz.jkl.com/v2.0/search?varible_that_you_want_to_pass='.$mobile_number.'&requestId=1616581154955&locale=en-US&sessionId='.$sessionid,
I create one small API what collect contact form informations from one website and store in database on another website in managment application what I also build.
On website where is contact form is this code:
// collect all fields
$save = array(
'oAuth'=>'{KEY}',
'secret'=>'{SECRET-KEY}',
'category'=>'Category',
'name'=>'Jon Doe',
'email'=>'jon#doe.com',
'phone'=>'123 456 7890',
// ... etc. other fields
);
// made GET request
$fields=array();
foreach($save as $key=>$val){
$fields[]=$key."=".rawurlencode($val);
}
// Set cross domain URL
$url='http://api.mydomain.com/';
// Send informations in database
$cURL = curl_init();
curl_setopt($cURL,CURLOPT_URL, $url.'?'.join("&",$fields));
curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cURL, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($cURL, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($cURL, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($cURL, CURLOPT_TIMEOUT, 2);
curl_setopt($cURL, CURLOPT_HTTPHEADER, array('Accept: application/json'));
$output=curl_exec($cURL);
curl_close($cURL);
usleep(1000);
// redirect
header("Location: http://somemysite.com/thank-you-page");
session_destroy();
exit;
My question is do to use cURL like now for this or to use header() function to send GET?
I ask because I not use output here and sometimes redirection start before cURL finish request.
What is faster way to send GET info and not lost data?
The redirection will not start before cURL finishes. What may happen is that cURL fails to load you remote page, and you don't handle that error. You should add something like this:
if($output === false || curl_getinfo($cURL, CURLINFO_HTTP_CODE) != 200) {
// Here you handle your error
}
If you are looking for an alternative to load remote webpages, you can set allow_url_fopen to true in your php.ini and then use this simple function instead of cURL:
$output = file_get_contents($url.'?'.join("&",$fields));
trying to send post request to api, to get an image back.
example url:
https://providers.cloudsoftphone.com/lib/prettyqr/createQR.php?user=1003123&format=png&cloudid=asdasdasd&pass=123123123
the above url works fine in the browser,
the api doesnt care if the request is get/post,
result of my code is always 'invalid input'.
code:
$url='https://providers.cloudsoftphone.com/lib/prettyqr/createQR.php';
$u = rand();
$p = rand();
$fields = array(
'user'=> urlencode($u),
'pass'=> urlencode($p),
'format'=> urlencode('jpg'),
'cloudid' => urlencode('test')
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
on a side note: is there a way to debug the request in order to see what is being sent ?
The URL provided isn't working for POST request. Here is resulting screenshot (I tried using Advance Rest Client)
However Its working perfectly with GET method. So you can continue using GET request method to generate QR code.
I agree that GET isn't much secure compare to POST method but in your case while requesting from curl user won't get to know about such URL parameters (userid, password). Because curl request will be sending from your web server and not from client/user's browser.
Later you can just output the response image you got from the api.
I am developing a script involving Php Curl to send sms using http://www.gysms.com/freesms.php
The page stores a cookie PHPSESSID and also a hidden field named token is passed during the posting.
I have written a script involving two curl requests. 1st curl request parse the page and obtain the token value .
Here is the code for that:
<?php
$phone = '9197xxxxxxx';
$msg = 'Hi this is curlpost';
$get_cookie_page = 'http://www.gysms.com/freesms.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $get_cookie_page);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$sabin = curl_exec($ch);
$html=explode('<input type="hidden" name="trigger" value="',$sabin);
$html=explode('"/>',$html[1]);
//store the token value to $html[0]
?>
Curl post is done using the following code:
<?php
$fields = array(
'trigger'=>urlencode($html[0]), //token value
'number'=>urlencode($phone), //phone no
'message'=>urlencode($msg) //message
);
//posting curl request
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');
$url = 'http://www.gysms.com/freesms.php';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
//execute post
$result = curl_exec($ch);
echo $result;
curl_close($ch);
?>
The sms is not sending Using the above code.
If the sms is sent It should show sms is send to-No.
I don't Know where I went wrong. Please help, I am new to PHP.
Finally this attempt is only for my educational purpouse.
Here is some code I came up with that worked. Hope it helps. Some explanations and feedback about your code follow.
<?php
$number = '14155556666';
$message = 'This is my text in all its glory.';
$url = 'http://www.gysms.com/freesms.php';
$cookieFile = tempnam(null, 'SMS');
$userAgent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0';
if (strlen($message) > 100) {
die('Message length cannot exceed 100 characters.');
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); // empty user agents probably not accepted
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // enable this - they check referer on POST
$html = curl_exec($ch);
// <input type="hidden" name="trigger" value="CXXrtmqVC7KbUnJ22UBodFy1kBj4ign5PsQ3qNR91nH2055307b4xP4"/>
if (!preg_match('/name=.trigger.\s+value=.([^\'"]+)/i', $html, $trigger)) {
die('Failed to locate hidden input value');
}
sleep(5); // without a slight delay, i often would not receive sms
$trigger = $trigger[1];
// build array of post values - all are important
$post = array('number' => $number,
'trigger' => $trigger,
'message' => $message,
'remLen' => 100 - strlen($message),
$trigger => 'Send Message');
// switch request to POST, use http_build_query to encode post data for us
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$html = curl_exec($ch);
if (strpos($html, '<b>Message sent to</b>') !== false) {
echo "Message sent!";
} else {
echo "<b>Message not sent :(</b><br /><br />";
echo $html;
}
I think you may have had trouble for several reasons:
A User-Agent should be specified in the request, they seem to reject if you leave it empty
I used http_build_query to build the POST string (preference)
You were missing 2 fields in the request, remLen, and the trigger value as the submit button
I often would not receive the messages if I didn't sleep a few seconds before sending the message after getting the trigger value.
In most of the cases where I didn't get the message, it still showed the "Message sent to phone #" on the screen even though it never came. Once I combined all the right things (sleep time, user agent, valid post fields) I would see the success message but also get the response.
I think the most critical thing left out from your code was that on the first request where you grab the trigger value, they also set a cookie (PHPSESSID) that you are required to capture. Without sending that on the POST request it was probably an automatic reject.
To get around this, make sure you capture cookies on the first request as well as subsequent requests. I chose to re-use the same curl handle for both requests. You don't have to do it that way, but you would have to use the same cookie file and cookie jar between requests.
Hope that helps.
I have a PHP script that does an HTTP request on behalf of the browser and the outputs the response to the browser. Problem is when I click the links from the browser on this page it complains about cookie variables. I'm assuming it needs the browsers cookie(s) for the site.
how can I intercept and forward it to the remote site?
This is how I forward all browser cookies to curl and also return all cookies for the curl request back to the browser. For this I needed to solve some problems like getting cookies from curl, parsing http header, sending multiple cookies and session locking:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// get http header for cookies
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
// forward current cookies to curl
$cookies = array();
foreach ($_COOKIE as $key => $value)
{
if ($key != 'Array')
{
$cookies[] = $key . '=' . $value;
}
}
curl_setopt( $ch, CURLOPT_COOKIE, implode(';', $cookies) );
// Stop session so curl can use the same session without conflicts
session_write_close();
$response = curl_exec($ch);
curl_close($ch);
// Session restart
session_start();
// Seperate header and body
list($header, $body) = explode("\r\n\r\n", $response, 2);
// extract cookies form curl and forward them to browser
preg_match_all('/^(Set-Cookie:\s*[^\n]*)$/mi', $header, $cookies);
foreach($cookies[0] AS $cookie)
{
header($cookie, false);
}
echo $body;
In fact, it is possible. You just have to take the cookie ofthe browser and pass it as a parameter to curl to mimik the browser.
It's like a session jacking...
Here is a sample code:
// Init curl connection
$curl = curl_init('http://otherserver.com/');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// You can add your GET or POST param
// Retrieving session ID
$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
// We pass the sessionid of the browser within the curl request
curl_setopt( $curl, CURLOPT_COOKIE, $strCookie );
// We receive the answer as if we were the browser
$curl_response = curl_exec($curl);
It works very well if your purpose is to call another website, but this will fail if you call your web server (the same that is launching the curl command). It's because your session file is still open/locked by this script so the URL you are calling can't access it.
If you want to bypass that restriction (call a page on the same server), you have to close the session file with this code before you execute the curl :
$curl = curl_init('http://sameserver.com/');
//...
session_write_close();
$curl_response = curl_exec($curl);
Hope this will help someone :)
From curl_setopt:
By default, libcurl always stores and loads all cookies, independent if they are session cookies or not.
However you may need to set cookies directly, which can be done using:
curl_setopt($ch, CURLOPT_COOKIE, 'foo=bar');
Which is the same as the Set-Cookie HTTP header. Check you're not using curl_setopt($ch, CURLOPT_COOKIESESSION, true) as this will make libcurl ignore some cookies.
You can't.
If you curl the request, you will need to parse the output, and replace all links so they go thru your server.
www.yourdomain.com/f?=www.someotherdomain.com/realpage
The only way this would work is if you use persistent cookies in your curl request. CURL can keep cookies itself. Assign a session ID to the cookie file (in curl) so subsequent requests get the same cookies. When a user clicks a link, you will need to curl the request again.
It is a security issue to allow site1 to set cookies for site2. Imagine if you could set cookies in the browser for paypal and trick the user into thinking they had logged int or some other malicious action.
The Cookie is usually sent with the HTTP request header like
Host stackoverflow.com
User-Agent ...
Accept-Language en-us,en;q=0.5
Referer http://stackoverflow.com/unanswered
Cookie bla=blabla;blubb=blu
So I guess that just have to modify the cookie part in your header.
PiTheNumber's answer was great but I ran into some issues with it that caused it to still print the headers to the page. So I adjusted it to use the more reliable curl_getinfo function. This version also follows redirects.
public function get_page_content( $url ) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_HEADER, 1);
// Forward current cookies to curl
$cookies = array();
foreach ($_COOKIE as $key => $value) {
if ($key != 'Array') {
$cookies[] = $key . '=' . $value;
}
}
curl_setopt( $ch, CURLOPT_COOKIE, implode(';', $cookies) );
$destination = $url;
while ($destination) {
session_write_close();
curl_setopt($ch, CURLOPT_URL, $destination);
$response = curl_exec($ch);
$curl_info = curl_getinfo($ch);
$destination = $curl_info["redirect_url"];
session_start();
}
curl_close($ch);
$headers = substr($response, 0, $curl_info["header_size"]);
$body = substr($response, $curl_info["header_size"]);
// Extract cookies from curl and forward them to browser
preg_match_all('/^(Set-Cookie:\s*[^\n]*)$/mi', $headers, $cookies);
foreach($cookies[0] AS $cookie) {
header($cookie, false);
}
return $body;
}