i have a curl function that visits a website, logs in to said website, stores the cookie file, then can later read the cookie file to visit a page that would normally require a login.
problem i am faced with is i want to save and retrieve the cookie file using a php variable but cant seem to get it to work.
$username = "myusername";
function getUrl($url, $method='', $vars='') {
$ch = curl_init();
if ($method == 'post') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies/$username.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies/$username.txt");
$buffer = curl_exec($ch);
curl_close($ch);
return $buffer;
}
i assume the syntax is wrong, and not that curl cant handle a variable as a location?
The problem is the scope of the $username variable. Because it's outside the function, it's not available inside the function. You should either add the username as a parameter of the function or use the global keyword so that it's accessible inside the function.
See http://ca2.php.net/manual/en/language.variables.scope.php for more information.
Related
I'm building an application using a local php file that takes post/get input and returns JSON results. I'm doing this to de-couple front and backend operation on the idea that it's possible to move the backend elsewhere eventually (and it's neat because you can test backend operation using only browser and URL variables.
To be clear, I have no immediate or even long-term plans to actually separate them: right now they're on the same server in the same folder even - I just have a single backend.php file pretending to be a remote server so that I can practice decoupling. Victory for this issue means calling CURL and having the backend recieve the session, the backend can change/update/addto the session, and the front end sees all changes (basically ONE session for front and back).
The problem is that I'm constantly fighting to get session to work between the two. When I make AJAX requests with Javascript, session works fine because it's a page loading on the same server so session_start() just works. But when I CURL, the session data is not transferred.
I've been fighting with this for months so my curl function is pretty messy, but I can't figure out the magic combination that makes this work. No amount of SO questions or online guides I've been able to find work consistently in this case:
// Call the backend using the provided URL and series of name/value vars (in an array)
function backhand($data,$method='POST') {
$url = BACKEND_URL;
// Make sure the backend knows which session in the db to connect to
//$data['session_id'] = session_id();
// Backend will send this back in session so we can see the the connection still works.
//$data['session_test'] = rand();
$ch = curl_init();
if ('POST' == $method) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$get_url = sprintf("%s?%s", $url, http_build_query($data));
$_SESSION['diag']['backend-stuff'][] = $get_url;
if ('GET' == $method) {
curl_setopt($ch, CURLOPT_PUT, 1);
$url = $get_url;
}
// Optional Authentication:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
# curl_setopt($ch, CURLOPT_VERBOSE, 1);
# curl_setopt($ch, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
// Retrieving session ID
// $strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
$cookieFile = "cookies.txt";
if(!file_exists($cookieFile)) {
$fh = fopen($cookieFile, "w");
fwrite($fh, $_SESSION);
fclose($fh);
}
#curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
#curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
#curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // Cookie aware
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // Cookie aware
// We pass the sessionid of the browser within the curl request
curl_setopt( $ch, CURLOPT_COOKIEFILE, $strCookie );
# session_write_close();
// Have to pause the session or the backend wipes the front
if (!$result = curl_exec($ch)) {
pre_r(curl_getinfo($ch));
echo 'Cerr: '.curl_error($ch);
}
curl_close($ch);
# session_start();
// "true" makes it return an array
return json_decode($result,true);
}
I call the function like so from the front-end to get results from the backend:
// Get user by email or ID
function get_user($emailorid) {
// If it's not an email, see if they've been cached. If so, return them
if (is_numeric($emailorid) && $_SESSION['users'][$emailorid])
return $_SESSION['users'][$emailorid];
return backhand(['get_user'=>$emailorid]);
}
So if I call "get_user" anywhere in the front, it will hop over to the back, run the db queries and dump it all to JSON which is returned to me in an associative arrays of values. This works fine, but session data doesn't persist properly and it's causing problems.
I even tried DB sessions for a while, but that wasn't consistent either. I'm running out of ideas and might have to build some kind of alternate session capability by using the db and custom functions, but I expect this CAN work... I just haven't figured out how yet.
You could keep the file system storage and share the file directory where are stored session with NFS if your backend web servers are on different servers.
You could also use http://www.php.net/manual/en/function.session-set-save-handler.php to set a different save handler for your session, but I am not sure that storing them on a database would be a good idea for I/O.
After brute-force trial and error, this seems to work:
function backhand($data,$method='POST') {
$url = BACKEND_URL;
// Make sure the backend knows which session in the db to connect to
//$data['session_id'] = session_id();
// Backend will send this back in session so we can see the the connection still works.
$data['session_test'] = rand();
$ch = curl_init();
if ('POST' == $method) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$get_url = sprintf("%s?%s", $url, http_build_query($data));
$_SESSION['diag']['backend-stuff'][] = $get_url;
if ('GET' == $method) {
curl_setopt($ch, CURLOPT_HTTPGET, 1);
$url = $get_url;
}
// Optional Authentication:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
// required or it writes the data directly into document instead of putting it in a var below
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
#curl_setopt($ch, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
// Retrieving session ID
$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
// We pass the sessionid of the browser within the curl request
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie );
curl_setopt($ch, CURLOPT_COOKIEJAR, 'somefile');
curl_setopt($ch, CURLOPT_COOKIEFILE, APP_ROOT.'/cookie.txt');
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
// Have to pause the session or the backend wipes the front
session_write_close();
if (!$result = curl_exec($ch)) {
pre_r(curl_getinfo($ch));
echo 'Cerr: '.curl_error($ch);
}
#session_start();
curl_close($ch);
// "true" makes it return an array
return json_decode($result,true);
}
I’m building a login system in php where I need to use credentials from another website, I’m using an API to login to another server and I’m doing it using cURL. The server where the login credentials are stored does create a cookie with a unique tolken after the user has logged in correctly and this cookie is important to view other webpages and interrogate this pages using other APIs.
This is what I’ve done so far and it seems to work fine, in the login controller php file I’ve got this code
$km_username = filter_var($_POST['userName'], FILTER_SANITIZE_STRING);
$km_user_password = $_POST['userPassword'];
$cookieFile = "cookies.txt";
if(!file_exists($cookieFile)) {
$fh = fopen($cookieFile, "w");
fwrite($fh, "");
fclose($fh);
}
$url = 'https://www.apiwebsite.com/api/login.jsp?';
$fields = array(
'userid' => $km_username,
'password' => $km_user_password
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // Cookie aware
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // Cookie aware
$content = curl_exec($ch);
curl_close($ch);
In the page where I want to interrogate the server to get other datas I’ve got
$dates = array(
'd_inizio' => '01/01/2017',
'd_fine' => '31/12/2017'
);
$url = "https://www.apiwebsite.com/api/ricevute.jsp?";
$cookie = "../../km-controllers/cookies.txt";
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($dates));
curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec ($ch);
So basically after user has logged into the website cURL saves a cookie txt file into my server and this allows me to use that file any other time i want to make another call using for example a different api
Now the question is: what happen if I’ve got more than one user logging into the system? Do I need to create x number of cookies according on how many users log into the system? Would it not be simpler to save the cookie into the user’s browser?
Yes, you should use a different file for each client. What you can do is use tempnam() to generate a unique filename for the client, and save this in a session variable, then use it as the cookie jar. The login controller can do this:
session_start();
if (!isset($_SESSION['cookiefile'])) {
$cookiefile = tempnam(".", "cookie");
$_SESSION['cookiefile'] = basename($cookiefile);
}
And then the later page can use
$cookie = "../../km-controllers/" . $_SESSION['cookiefile'];
When the user logs out, you should delete this file and remove the session variable.
There's nothing that will automatically pass the cookies through from the curl session to the client browser or vice versa. If you don't want to save the cookies in a file, you can use curl_getinfo($ch, CURLINFO_COOKIELIST) to get the cookies, but you'll then have to parse the info yourself, and later use CURLOPT_COOKIE to set each cookie when making future calls. The cookie file automates all this.
Full code for login controller.
session_start(); // This needs to be at the very beginning of your script, before anything that produces output
//...
$km_username = filter_var($_POST['userName'], FILTER_SANITIZE_STRING);
$km_user_password = $_POST['userPassword'];
if (!isset($_SESSION['cookiefile'])) {
$cookieFile = tempnam(".", "cookie");
$_SESSION['cookiefile'] = basename($cookiefile);
file_put_contents($cookieFile, "");
}
$cookieFile = $_SESSION['cookiefile'];
$url = 'https://www.apiwebsite.com/api/login.jsp?';
$fields = array(
'userid' => $km_username,
'password' => $km_user_password
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // Cookie aware
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // Cookie aware
$content = curl_exec($ch);
curl_close($ch);
And the later interrogator:
session_start(); // at very beginning
// ...
$dates = array(
'd_inizio' => '01/01/2017',
'd_fine' => '31/12/2017'
);
$url = "https://www.apiwebsite.com/api/ricevute.jsp?";
if (!isset($_SESSION['cookiefile'])) {
die("no cookie file");
}
$cookie = "../../km-controllers/" . $_SESSION['cookiefile'];
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($dates));
curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec ($ch);
I have seen some of the questions that others have asked regarding this same issue but I don't seem to be having much luck in my situation and would appreciate some clarification.
I need to pass a session variable from domain1.com to domain2.com. I have full access to both domains. I am using cURL to have domain1.com/caller.php access domain2.com/receiver.php. Once cURL finishes executing I get a status returned. If that status is good I use header("Location: auto_submit.html") to load a page that automatically submits a form/redirects to domain2.com/test.php. However when the page loads the session variable is not set. Here is what I have in domain1.com/caller.php
...
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "domain2.com/receiver.php");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $result[0]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER , true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
$curl_result = json_decode(curl_exec($ch));
curl_close($ch);
if ($curl_result->status === 1)
{
header("Location: ./auto_submit.html");
exit;
} else {
foo();
}
...
auto_submit.html just redirects to domain2.com/test.php.
What, if anything, do I need on domain2.com/test.php so that it will use the information in the cookie file and will be accessible in $_SESSION?
I have tried all several methods and approaches to this problem and I'm stumped. I'm trying to log into www.senderscore.org with php. The site's log in is a post form to their index page. I need to do this because I need to lookup several IPs and log the information on a regular basis. I have tried posting with curl but I have had no luck. Every attempt just returns the page as if I did not attempt to log in. If anyone could help out with a code snippet I'd appreciate it very much.
edit: The latest attempt's block of code. this is the code inside a class function.
$username= $this->username;
$password= $this->password;
$url = 'www.senderscore.org/index.php';
$fields = array(
'email'=>$username,
'password'=>$password,
'action'=>"localLogin",
'Submit'=>"Sign in",
'remember'=>'1'
);
$postvars='';
$sep='';
foreach($fields as $key=>$value)
{
$postvars.= $sep.urlencode($key).'='.urlencode($value);
$sep='&';
}
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,$url);
curl_setopt($curl,CURLOPT_POST,true);
curl_setopt($curl,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($curl);
if ($data === false) {
$data = curl_error($curl);
}
curl_close($curl);
return $data;
Try to look at this script, it should work with post; i haven't tested it:
$username = 'your_username';
$password = 'your_password';
$loginUrl = 'http://www.path-to-login.com/login/';
//init curl
$ch = curl_init();
//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);
// ENABLE HTTP POST - this is important in your case
curl_setopt($ch, CURLOPT_POST, 1);
//Set the post parameters - make sure to match username and password
curl_setopt($ch, CURLOPT_POSTFIELDS, 'user='.$username.'&pass='.$password);
//Handle cookies for the login
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
//not to print out the results of its query.
//Instead, it will return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute the request (the login)
$store = curl_exec($ch);
//the login is now done and you can continue to get the
//protected content.
//set the URL to the protected file
curl_setopt($ch, CURLOPT_URL, 'http://www.site-logging-into.com/protected/file.zip');
//execute the request
$content = curl_exec($ch);
//save the data to disk
file_put_contents('~/file.zip', $content);
here´s my problem:
I´m trying to get the content of a website that first needs a login. I wanted to solve this via cURL.
First I´m connecting to the Login-Page, than to a page that requires the login.
I get some Cookies in my cookie file back, but when I try to see the content of the page that requires a login before, I only get redirected to (get the content of) the login page.
Seems that parsing my login cookie or whatever fails, so the website don´t remeber that I logged in.
Heres is my php-Code so far:
<?php
$loginUrl = 'https://www.****./login.html';
$loginFields = array('j_username'=>'***', 'j_password'=>'**'); //login form field names and values
$remotePageUrl = 'https://www.***/myPage/index.html'; //url of the page I want the content
$login = getUrl($loginUrl, 'post', $loginFields); //login to the site
echo $remotePage = getUrl($remotePageUrl); //get the remote page
function getUrl($url, $method='', $vars='') {
$ch = curl_init();
if ($method == 'post') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
}
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIESESSION, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'C:\\xampp\htdocs\***\cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'C:\\xampp\htdocs\****\cookies.txt');
$buffer = curl_exec($ch);
if (curl_error($ch)) echo curl_error($ch);
curl_close($ch);
return $buffer;
}
?>
Any ideas? Searched now for hours in the web, and didn´t find a solution yet.
Thanks!
I did not find any solution. Nevertheless I did all the work manually and don´t need the programm anymore, anyway thanks for the comments :)