I am working on creating a system which is secured by passing tokens from page to page to verify the validity of requests. The token is to be generated on the login page (as it only needs to be generated once) and then passed through to the main page. However, there is an intermediate PHP script which is being run to log the user in, and I am not sure how to take the posted token and pass it on to the main page.
In short, I need to post the token from the login page to the intermediary script, and then from the script to the main page, and I'm not sure how to do that.
If all 3 pages are on the same host, use a cookie or a session.
Store the data in a cookie/session instead:
session_start();
$_SESSION['token'] = 'yourTokenHere'
See PHP Sessions
I wrote this a long time ago:
function postheader($url, $server, $cookies, $daten)
{
$temp=array();
$out = "POST ".$url." HTTP/1.1\r\n";
$out .= "Host: ".$server."\r\n";
if(count($cookies)>0)
{
$out .= "Cookie: ";
foreach($cookies as $name=>$value)
{
$temp[] = $name."=".$value;
}
$out .= implode("; ",$temp);
$out .= "\r\n";
}
$out .= "User-Agent: Mozilla/4.0\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$temp=array();
foreach($daten as $key=>$data)
{
$temp[] = $key."=".urlencode($data);
}
$temp=implode("&",$temp);
$out .= "Content-Length: ".strlen($temp)."\r\n";
$out .= "\r\n";
$out .= $temp."\r\n";
return $out;
}
$fp = fsockopen($server, 80, $errno, $errstr, 30);
if (!$fp)
die( "$errstr ($errno)<br />\n");
$out=postheader($url, $server, $cookies, $daten);
//echo $out;
fwrite($fp, $out);
while (!feof($fp))
{
$string.= fgets($fp, 128);
}
fclose($fp);
$daten should be a one dimensional associative array containing the data you want to send via the post request. For cookies, just add an empty array.
$server is the host address, and $url is only the address on the server, e.g.
$server="stackoverflow.com";
$url="/post.php";
$string will contain the whole response including the headers. If you don't want them, do a substring from the first "\r\n\r\n" occurence.
You can use Client side cookies:
<?php
setcookie("token", $myToken);
?>
The biggest fault with this method is that it absolutely requires the user to have cookies enabled on their browser. In highly secure situations a user may not have cookies enabled so this method wouldn't work for them.
Use $_SESSION global variable:
<?php
$_SESSION['token'] = $myToken;
?>
As previous variant, it requires cookies to be enabled.
Add $_GET parameter to URI string:
http://example.com?token=f4FArqk53Gwr4fESC73FedG48Trd3YEj
The biggest fault of this method is that your URI string will look very complex.
Also state information will be lost if user will manually modify URI.
Or pass everything in Hidden form fields:
Unfortunately it requires you to submit a form on every page.
You can do it with jQuery.
Some examples are here.
On further consideration, it looks like I was making things much more complicated than they needed to be. Thank you all for your help, but the solution seems to be that I should be a bit more intelligent.
Related
I am working on twitter login integration with website. I don't have cURL installed in my server and I am not allowed to install that.
Twitter code is working fine for login. But while using request_token curl is used to send callback URL with that URL and getting the token response. In this same case I want to get the response from that URL without using Curl in PHP. Is it possible?
Curl code now used:
$response = curl_exec($ci);
The above response I need without using Curl.
How to get the response from url without Curl
You don't have to necessarily use cURL, there can be many ways. One of those is:
$response=file_get_contents($ci);
Edit:
You can also use fsockopen, here is an example from PHP.net
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
I'm trying to have the PAYPAL IPN work with 2 different sites, I can't get the php script to know which database to work with. Here's my script.
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
// If testing on Sandbox use:
//$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
// assign posted variables to local variables
$custom = $_POST['item_name'];
//Config file for 1st database
if($custom=="1"){
require_once("../config.php");
//Script to execute
}
//Config file for 2nd database (different site)
if($custom=="2"){
require_once("../config.php");
//Script to execute
}
Your code is making a lot of assumptions and isn't very defensive. It's assuming the form was posted, that it was successfully populated, that $_POST['item_name'] will contain only the strings '1' or '2' and that your script is running in a path which is one folder deep to a directory containing config.php...and that regardless of the condition, the same config.php will be loaded and miraculously know what it needs to do.
What would make more sense is something like this:
try
{
if(isset($_POST['site_name']))
{
require_once('../configs/' . $_POST['site_name'] . '/config.php');
if(!isset($some_var_declared_inside_config_file))
{
throw new Exception('Config not loaded');
}
}
else
{
throw new Exception('Site name not provided');
}
}
catch(Exception $e)
{
echo $e->getMessage();
}
Then you could have your configs setup like so:
/www/paypal.php
/configs/sitea/config.php
/configs/siteb/config.php
/configs/sitec/config.php
I found a great script for this that worked great. It automatically send the paypal response to the correct site based on the email.
http://www.scriptomart.com/view-item/15-Paypal-IPN-Multiple-Email-Accounts.html is the script but the one I bought wasn't free so you may have to look for that one. I can't find the exact link.
I'm setting up a simple paypal button. When clicked, I need to write the order into my db and then redirect it via POST to paypal. The database part works just fine, however the POST to paypal doesn't.
I'm using the code by wez furlong to send a post request to the paypal server and need to process the response in order to redirect the client correctly (I need to get the location from the response).
In the end, this should behave just like a normal paypal "buy now" button, redirecting the user to paypal when clicked.
I just can't seem to get at the response and the paypal documentation is extremely vague on this. How do I extract the proper url for redirecting the client?
Any help appreciated!
Tobias
Here is how I implemented this functionality on my website. It is working fine:
Code to display the Paypal button:
Content += "<br/><a href='javascript:Pay();'><img src='http://www.example.com/images/paypal_checkout_button.jpg' alt='Secure payment through PayPal' border='0' /></a><br/><br/>";
Pay() is the javascript function called when the client clicks the button.
Code of function Pay()
function Pay() {
var MessageParam = "msgjson=" + JSON.encode(msgJSON) + "&invoicejson=" + JSON.encode(invoiceJSON);
var myRequest = new Request({url:"http://www.example.com/savetransaction.php", onSuccess: function(InvoiceId) {CallPayPal(InvoiceId);}}).post(MessageParam);
}
Function Pay does two things:
1 - submits the details of the transaction to a PHP script (savetransaction.php) running on the server. This script saves the transaction in a database. Note that the transaction is saved as Pending in the database. It will change to Paid once I receive confirmation from Paypal that it has been paid. Script savetransaction.php returns an invoice id number, which is the id from the database after the insert. This is the unique identifier that identifies this transaction throughout the payment process. I will send this number to paypal and it will send it back to me in the payment confirmation.
2 - onSuccess it calls function CallPayPal(InvoiceId), which will send the client to Paypal (see below).
Code of function CallPayPal(InvoideId)
function CallPayPal(InvoiceId) {
var PayPalUrl = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_xclick-subscriptions&business=YOURCODEHERE&lc=US&item_name=YOURITEMNAMEHERE&item_number=YOURITEMNUMBER&no_note=1&no_shipping=2&rm=1&return=URL_OF_SCRIPT_THAT_WILL_HANDLE_PAYPAL_RESPONSE&cancel_return=URL_OF_SCRIPT_THAT_WILL_BE_CALLED_IF_CLIENT_CANCEL_PAYMENT_AT_PAYPAL&src=1&a3=" + invoiceJSON.AmtSubs + "&p3=1&t3=M¤cy_code=USD&bn=PP%2dSubscriptionsBF%3abtn_subscribeCC_LG%2egif%3aNonHosted";
window.open(PayPalUrl + "&invoice=" + InvoiceId,"_self");
}
You will need to change the paypal url to fit your needs. Mine is for a subscribe button. Note that I include the InvoiceId at the end. This will be received by PayPal and sent back in the response.
When the client finishes paying, Paypal will send him back to the address I included in the variable return. Paypal will append a transaction code to the url. See below the php script where I handle the return from Paypal:
Code for PayPalPDT.php
$req = 'cmd=_notify-synch';
$tx_token = $_GET['tx'];
$auth_token = "enter your own authorization token";
$req .= "&tx=$tx_token&at=$auth_token";
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
//$fp = fsockopen ('http://www.sandbox.paypal.com', 80, $errno, $errstr, 30);
// If possible, securely post back to paypal using HTTPS
// Your PHP server will need to be SSL enabled
// replace www.sandbox.paypal.com with www.paypal.com when you go live
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if (!$fp)
{
// HTTP ERROR
}
else
{
fputs ($fp, $header . $req);
// read the body data
$res = '';
$headerdone = false;
while (!feof($fp))
{
$line = fgets ($fp, 1024);
if (strcmp($line, "\r\n") == 0)
{
// read the header
$headerdone = true;
}
else if ($headerdone)
{
// header has been read. now read the contents
$res .= $line;
}
}
// parse the data
$lines = explode("\n", $res);
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0)
{
for ($i=1; $i<count($lines);$i++)
{
list($key,$val) = explode("=", $lines[$i]);
$keyarray[urldecode($key)] = urldecode($val);
}
$firstname = $keyarray['first_name'];
$lastname = $keyarray['last_name'];
$itemname = $keyarray['item_name'];
$amount = $keyarray['payment_gross'];
$invoiceid = $keyarray['invoice'];
$profileid = $keyarray['subscr_id'];
// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment
// show receipt to client
}
}
I hope this helps. Please feel free to ask follow up questions.
Good luck!
Use GET variables if you're using a header redirect.
For example: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=yourpaypalemail&amount=theamount&item_name=the%20item%20name
See also 'HTML variables for Website Payments Standard' at https://merchant.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables for additional variables you could use.
Since you need to redirect the user to PayPal, you can't do a POST from the server to make that happen.
Instead, I'd suggest you use some AJAX and intercept the button click. When the button gets clicked, your JavaScript function can call a URL on your server to write out the data, and then also send the user off to PayPal.
The code on wezfurlong is for having the server do a PHP post to paypal, not for redirecting the client. I think I implemented this by creating a html form that points to paypal and a javascript command to submit it, something like:
<html><body>
<form method='post' action='paypalurl'>
<input name='some required field' blah blah...>
</form>
<script>
document.forms[0].submit();
</script>
</body></html>
I am kinda new to PHP however I used JSP a lot before (I have quite information) and everything was easier with Java classes.
So, now, I want to perform a POST request on a HTTPS page (not HTTP) and need to get returned cookies and past it to another GET request and return the final result. Aim is to make a heavy page for mobile phones more compatible to view in a mobile browser by bypassing the login page and directly taking to the pages which are also served in an ajax user interface.
I am stuck, my code does not work, it says it is Bad Request.
Bad Request
Your browser sent a request that this
server could not understand. Reason:
You're speaking plain HTTP to an
SSL-enabled server port. Instead use
the HTTPS scheme to access this URL,
please.
<?php
$content = '';
$flag = false;
$post_query = 'SOME QUERY'; // name-value pairs
$post_query = urlencode($post_query) . "\r\n";
$host = 'HOST';
$path = 'PATH';
$fp = fsockopen($host, '443');
if ($fp) {
fputs($fp, "POST $path HTTP/1.0\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-length: ". strlen($post_query) ."\r\n\r\n");
fputs($fp, $post_query);
while (!feof($fp)) {
$line = fgets($fp, 10240);
if ($flag) {
$content .= $line;
} else {
$headers .= $line;
if (strlen(trim($line)) == 0) {
$flag = true;
}
}
}
fclose($fp);
}
echo $headers;
echo $content;
?>
From past experience, I've never used PHP's internal functions like fsocketopen() for external data posting. The best way to do these actions are using CURL, which gives much more ease and is massively more powerful for developers to leverage.
for example, look at these functions
http://php.net/curl_setopt
and look at the one with URL, POST, POSTDATA, and COOKIESFILES which is for .JAR, which you get then retrieve and that you can use file_get_contents() to send the data using GET.
I am accessing a url which needs authentication, so for authentication i am using cookie something like this
$out = "GET $path HTTP/1.0\r\nHost: $host\r\nCookie: user=$cookie\r\n\r\n";
$fp = fsockopen($host, 80, $errno, $errstr, 30) or htmlerror('Bandwidth limit exceeded, please try again later.');
fwrite($fp, $out);
so i wanted to know whether instead of cookie how can i use directly username and password in variable $out
Thank You
I had a quick view on HTTP GET REQUEST, you might try to insert something into the query part of the URI
$out = 'GET /*?*username=$user&password=$encryptedPW HTTP/1.1'
$out .= '/n' . 'Host: $host'
it didnt work, just using it with cookie