I am using the Furk.net API and I have managed to successfully login using a curl function and submitting the post data to the proper URL (http://api.furk.net/api/login/login). When I echo the results, I get a success message and the cookie is successfully stored on my server. However, when I try to then retrieve information from the API, it gives me access denied. I'm wondering why my cookie isn't being used for all following requests?
function getUrl($url, $method='', $vars='') {
global $megauser;
$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, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
$buffer = curl_exec($ch);
curl_close($ch);
return $buffer;
}
$login_data = array(
'login' => 'user',
'pwd' => 'pass'
);
echo getUrl('http://api.furk.net/api/login/login','post', $login_data);
If I try another request on the API using this same function while the cookie exists, I get access denied, but if I try the same request in my browser while logged in, I get the appropriate results.
When you login, you don't need to save the cookie. You will receive an answer from the API with the apy_key.
You need to keep that key, and send it along with all your other requests to the API (As as POST parameter)
And you should not use the cookie and the api_key at the same time, as some requests are denied if both are sent.
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 am trying to access a website's protected web page where I need to post some JSON data to a page, but it always shows status code 200 and redirects me to a page which says
"Please enable browser cookie" and then shows me the login page as a response, both of the curl executions return 200 status code. I also give the cookie.txt correct permission i.e, 644. BUT I FOUND THAT COOKIE.TXT is not modifying
any help would be appreciated.
php curl code:
<?php
//username and password of account
$username = trim($_POST["email"]);
$password = trim($_POST["password"]);
echo "username=$username pass:$password";
$loginUrl = 'https://www.pogrande.com/login.php?action=process';
//The username or email address of the account.
define('USERNAME', $username);
//The password of the account.
define('PASSWORD', $password);
//Set a user agent. This basically tells the server that we are using Chrome ;)
define('USER_AGENT', 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2309.372 Safari/537.36');
//Where our cookie information will be stored (needed for authentication).
define('COOKIE_FILE', 'cookie.txt');
//URL of the login form.
define('LOGIN_FORM_URL', 'https://www.pogrande.com/login.php');
//Login action URL. Sometimes, this is the same URL as the login form.
define('LOGIN_ACTION_URL', 'https://www.pogrande.com/login.php?action=process');
//An associative array that represents the required form fields.
//You will need to change the keys / index names to match the name of the form
//fields.
$postValues = array(
'email_address' => USERNAME,
'password' => PASSWORD
);
//Initiate cURL.
$curl = curl_init();
//Set the URL that we want to send our POST request to. In this
//case, it's the action URL of the login form.
curl_setopt($curl, CURLOPT_URL, LOGIN_ACTION_URL);
//Tell cURL that we want to carry out a POST request.
curl_setopt($curl, CURLOPT_POST, true);
//Set our post fields / date (from the array above).
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postValues));
//We don't want any HTTPS errors.
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
//Where our cookie details are saved. This is typically required
//for authentication, as the session ID is usually saved in the cookie file.
curl_setopt($curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
//Sets the user agent. Some websites will attempt to block bot user agents.
//Hence the reason I gave it a Chrome user agent.
curl_setopt($curl, CURLOPT_USERAGENT, USER_AGENT);
//Tells cURL to return the output once the request has been executed.
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//Allows us to set the referer header. In this particular case, we are
//fooling the server into thinking that we were referred by the login form.
curl_setopt($curl, CURLOPT_REFERER, LOGIN_FORM_URL);
//Do we want to follow any redirects?
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
//Execute the login request.
curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
echo "status=$status";
//Check for errors!
if(curl_errno($curl)){
throw new Exception(curl_error($curl));
}
$url = $_POST['url'];
$content = $outp;//json_encode("your data to be sent");
//We should be logged in by now. Let's attempt to access a password protected page
curl_setopt($curl, CURLOPT_URL, $url);
//Use the same cookie file.
curl_setopt($curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
//Use the same user agent, just in case it is used by the server for session validation.
curl_setopt($curl, CURLOPT_USERAGENT, USER_AGENT);
//We don't want any HTTPS / SSL errors.
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
//Execute the GET request and print out the result.
curl_exec($curl);//the login is now done and you can continue to get the
//protected content.
/*
$url = $_POST['url'];
$content = $outp;//json_encode("your data to be sent");
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array("Content-type: application/json"));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
*/
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 201 ) {
die("Error: call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}
curl_close($curl);
$response = json_decode($json_response, true);
//alert($response);*/
}
}
?>
I found a script and modified it, hoping to returrn the contents of a login page. However, it seems that the page won't let me log in.
using var_dump($_POST); and print_r($_POST); gives me a blank array:
array(0) {
}
Array
(
)
So I don't know how to do it. The website is https://create.kahoot.it/login
This is the code I am running:
<?php
$username = 'USERNAME';
$password = 'PASSWORD';
$loginUrl = 'https://create.kahoot.it/login';
//init curl
$ch = curl_init();
//Set URL
curl_setopt($ch, CURLOPT_URL, $loginUrl);
//HTTPS
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1);
//try to echo post variables
var_dump($_POST);
print_r($_POST);
//Set the post parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, 'user='.$username.'&pass='.$password);
//Handle cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
// to return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//login
$store = curl_exec($ch);
//put page details in file
file_put_contents("test.txt",$store);
?>
--EDIT--
response headers + authentication page stuff
by changing the postman from POST to GET it returns {"error":"Authentication failed","exception":"Authentication failed","error_description":"Authentication token of type [class no.mobitroll.core.security.shiro.tokens.SessionToken] could not be authenticated by any configured realms. Please ensure that at least one realm can authenticate these tokens.","timestamp":1499789957919,"duration":0,"errorCode":0}
first use this code and debug your issue.
$info = curl_getinfo($ch);
print_r( $info );
if you are requesting HTTPS check
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
405 error probably for un-permitted methods. e.g. Making a GET call, when only POST is permitted, or vice versa.
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?
Im using MAMP on a Mac running OS X Lion.
I need to connect to a remote site sending the cookie.
All goes well except for the cookie part.
For the cookie part I'm using this code:
$cookieFile = dirname(__FILE__).'/cookie.txt';
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile);
The CURLOPT_COOKIEJAR part does create a cookie, but on a subsequent request CURLOPT_COOKIEFILE doesn't add a cookie header. I've checked this using HTTPScoop (a Fiddler like tool).
Any idea what might be the problem?
EDIT:
Im connecting to a ASP.Net site. Problem seems to be the im not getting a ASP.NET_SessionId cookie. The cookie i do get has a key without a value, thats probably the reason why it isn't posted.
Any idea how to force the server to send a session cookie?
We'd really need to see more code, but here is a sample bit I have which collects a session cookie from an initial request then uses it in a subsequent POST. It uses an anonymous proxy to run a GET request on an arbitrary URL, hopefully it helps you (to be clear though it doesn't use the COOKIEJAR, but I feel it may still be helpful).
<?php
define('TARGET_URL', 'http://moxune.com');
echo 'Sending initial request' . PHP_EOL;
$aHeaders = get_headers("http://420proxy.info");
foreach($aHeaders as $sHeader) {
if(stripos($sHeader, 'set-cookie') !== false) {
// extract the cookie from the first response
$aCookie = explode(':', $sHeader);
$sCookie = trim(array_pop($aCookie));
$oCookie = http_parse_cookie($sCookie);
echo 'Cookie extracted, trying to POST now' . PHP_EOL;
// OK, now let's try the POST request
$ch = curl_init('http://420proxy.info/includes/process.php?action=update');
curl_setopt($ch, CURLOPT_REFERER, '420.proxy.info');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_COOKIE, $sCookie);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect: 100-continue'));
//curl_setopt($ch, CURLOPT_COOKIE, http_build_cookie((array)$oCookie));
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'u' => TARGET_URL,
'allowCookies' => 'off',
'encodeURL' => 'off',
'stripJS' => 'on'
)
);
$response = curl_exec($ch);
die(var_dump($response));
}
}