Using JSONP on a site say xyz.com, I am calling a site abc.com/test.php. However, everytime I call this site, I get a new session id in IE6 and IE7. In other browsers it remains constant.
The code of test.php is something like:
<?php
session_start();
echo session_id();
?>
However, after I visit http://abc.com/test.php in another window, and then refresh my page at xyz.com with JSONP code, it shows a constant ID. I have no clue why. Any suggestions?
This happens only in IE6 and IE7. Rest all work as expected. Somehow IE6 and IE7 dont seam to retain the session id (i.e. cookie name) until I actually visit the site in another window.
Based on some info on PHP.net, will adding this header work?
<?php header('P3P: CP="CAO PSA OUR"'); ?>
Quote:
"workaround when using session variables in a .php file referred by a frame (.html, or
other file type) at a different server than the one serving the .php:
Under these conditions IE6 or later silently refuses the session cookie that is
attempted to create (either implicitly or explicitly by invoquing session_start()).
As a consequence, your session variable will return an empty value.
According to MS kb, the workaround is to add a header that says your remote .php page
will not abuse from the fact that permission has been granted.
Place this header on the .php file that will create/update the session variables you want:"
If this doesn't solve it, it might be something to do with the HTTReferer as IE doesn't send it on requests that initiate from JavaScript (e.g. doing this in IE will fail to send the HTTR Referer document.location.href = 'http://example.com/';
Related
I am using query.cookie.js to set a cookie as in the following code:
$.cookie('objectID', objectID);
var theTarget = '/mvtm?page_id=4252' ;
window.open(theTarget, "Detail").focus();
Then in the targeted page, in an iframe, I am using PHP code to access the cookie:
$variable = $_COOKIE['objectID'];
However, that index in $_COOKIE is undefined! I can see the cookie in the browser in both the page where it is set and the targeted page (using browser developer tools). These pages are all in the same domain (localhost) and the cookies are intended to be simple session cookies.
Does the fact that both the set and get code above are in iframes have any bearing? I've tried this in both Safari and Firefox.
Make the cookie available across the entire domain by setting the path
$.cookie('objectID', objectID, { path: '/' });
by default it's only available on the page where it was created.
Is it possible to disallow direct access to a PHP file and allow the access only if it's redirected from other PHP file?
For example, access to loading.php should be only allowed if it's redirected from example.php page. How how can I do that?
I hope you understand what I mean. If not, please ask me, and I will try to explain better.
example.php
session_start();
$_SESSION['loading']='yes';
loading.php
session_start();
if($_SESSION['loading']=='yes'){
/all good
}else{
//bad, redirect back or whatever
}
$_SESSION['loading']=''; // clear session var
You can check referer, but it not secure:
loading.php
<?php
if($_SERVER['HTTP_REFERER']!=='http://yoursite/example.php')
die('Denied');
--
or you can set visited flag in session
example.php
<?php
$_SESSION['isVisitedExample'] = true;
loading.php
<?php
if(!isset($_SESSION['isVisitedExample']))
die('Denied');
--
or in cookie (not secure)
example.php
<?php
setcookie('isVisitedExample', 1);
loading.php
<?php
if(!isset($_COOKIE['isVisitedExample']))
die('Denied');
--
or mix this methods
Test for the variable $_SERVER['HTTP_REFERER']. (yes, the incorrect spelling is what must be used.) That variable contains the URL of the site that a user came from. The REFERER header is blank or '-' if the page is accessed directly.
The code for this would look something like the following:
if (empty($_SERVER['HTTP_REFERER']) or $_SERVER['HTTP_REFERER'] == '-') {
exit; // do nothing if hit directly.
}
// The real page logic goes here.
If you want to only allow the loading page from a specific URL, then you may test for that URL instead of testing for empty().
Please be aware that the REFERER header is sent by the browser and easily spoofed. That said, checking the referer header is useful for blocking other sites from directly loading images from your site.
Another option would be to use sessions and session variables to check that someone hit the appropriate page before the loader page.
Basic situation and basic relevant info:
I have a php code that executes before the opening <doctype> tag. The hope was to (if necessary) send a redirect based on user's browser's language preferences before anything else loads.
The script attempts to do two things based on highest supported language preference:
Use php: setcookie() to create a cookie with the two-letter language code.
Example cookie name = value: x_language = es
Use php: header("Location: " . $requestedSite); to redirect to a subdomain,
Example domain: es.domain.com
Example:
if (isset($_COOKIE['x_language'])) {
-Determine correct subdomain based on cookie value-
-If not currently on that subdomain, redirect to it-
} else {
setcookie('x_language','es',time() + 31536000 ,'/','.domain.com' );
header("Location: " . $requestedSite);
}
The problem:
Firefox works perfectly. Chrome (and other browsers) fail to recognize the cookies at all.
I've boiled it down to this:
print_r($_COOKIE) works properly in Firefox, and returns a lovely, populated array.
print_r($_COOKIE) fails in Chrome, and returns an empty array.
This is the core of the problem, my function doesn't recognize the existence of a cookie because Chrome doesn't.
I've made sure every browser accepts cookies.
I've checked dev tools to make sure the cookie is in place on all browsers, (it is).
I realize a cookie's value isn't available until the next page load, but that isn't an issue here. Even after it is set, it won't read.
There is no output above the initial setcookie();
So how do I get Chrome (and other browsers) to recognize its own cookies?! Does anyone know why this would all work flawlessly on Firefox but fail elsewhere?
On a lark I decided to try this. I created a file that only contains:
<?php
print_r($_COOKIE);
?>
Again, I see the cookie array in Firefox. Meanwhile, in Chrome, IE, Opera, Safari, I get an empty array. Could this be a server issue?
OP returns with answer:
Alright, I'm adding this as an 'Answer' in case anyone else comes across this (totally bizarre) behavior and lands here:
It turns out my hosting provider was doing some seriously aggressive caching with my WordPress site that I was unaware of.
At the time I posted my question, I didn't think being on WordPress was relevant, but apparently it was.
Basically it was doing this:
With a clean Cache:
Visitor 1 visits the site.
The php processes and produces output as expected.
Visitor 1 is served php output (based on his browser's parameters and such).
Visitor 2 visits the site. Visitor 2 sees *Visitor 1's version of the site.
The php is processed once and only once per Cache-clear.
This caching behavior meant that accessing cookies through php was simply not going to work right, but accessing them with Javascript WOULD work.
(Important note: It turns out the above-stated caching behavior is disabled for any user viewing the site while logged into wordpress, and this is common behavior for WordPress Cache plugins. That is why I was seeing different behavior in Firefox than I saw in other browsers, because I was actively logged in with Firefox. This could be a helpful piece of information for someone out there.)
My solution:
Use Javascript to run an AJAX query to a .php file which would process the language preferences of the visitor and return the output as a 2-character code, (i.e. 'en' 'es' 'pt' 'de', etc).
Using AJAX to call php allowed me to use php's server-side access to a browser's language preferences while circumventing the super-agro caching of my host.
I hope this helps someone! And thanks to everyone who tried to help me out with this.
I was not having this problem with the code below. I was able to go to example.com and be redirected immediately to en.example.com and see the cookie in $_COOKIES. If I used en.example.com?set=fr I would be redirected to fr.example.com every time I tried example.com. Hopes this is what you were looking for!
<?php
print_r($_COOKIE);
if(isset($_GET['nuke'])) {
setcookie('x_language','',time()-1000,'/','.example.com');
echo 'It has been nuked!';
exit;
} else if(isset($_GET['set'])) {
setcookie('x_language',$_GET['set'],time() + 31536000, '/','.example.com');
$_COOKIE['x_language'] = $_GET['set'];
}
if (isset($_COOKIE['x_language'])) {
$redirect = $_COOKIE['x_language'].'.example.com';
if($_SERVER['HTTP_HOST'] != $redirect)
header('Location: http://'.$redirect);
} else {
setcookie('x_language','en',time() + 31536000,'/','.example.com');
$redirect = 'http://en.example.com';
header('Location: '.$redirect);
}
echo '<br />Cookie: '.$_COOKIE['x_language'].' Domain: '.$_SERVER["HTTP_HOST"];
?>
I really don't know what the issue is here.
I have a script called "login.php" that works perfectly. It's called with AJAX, and if it returns successfully, the page refreshes and the user is logged in. The cookie is set on that page with
setcookie("main", $row[0], time() + 3600, "/")
Then I have a script called "logout.php". It is called the same way (AJAX and then page refresh). It only has two lines:
<?php
setcookie("main", "", time() - 3600, "/");
echo "Done";
?>
Calling it form the page wasn't working, so I just loaded logout.php in the browser. The output was "done" but checking my cookies in Chrome showed me that the cookie was still set to "1" (which was $row[0]) and to expire at the time set in login.php.
login.php and logout.php are both in the same folder, the root directory, which is the same folder as everything else.
Earlier, this was working, but the only changes I've made are to make the title bar on the website its own file (still in the root directory) and to take the JavaScript functionality for the Logout button, which is just an AJAX call and some jQuery hover effects, and make it its own script file, which is in the _js folder. But I didn't change logout.php at all, so it should still work when I navigate directly to it, right? Is there something wrong with my setcookie command, or what other problem could be causing it?
EDIT: I tried setting it to expire in 100 seconds instead of -3600, and then tried changing its name so I could recognize it as a totally separate cookie. Neither of them made it show up. The cookie simply isn't getting set at all.
EDIT 2: I reverted to the last commit, and everything is working again. I don't know why reorganizing my site by creating some new files (logout.php isn't changed at all) makes a certain script unable to create cookies.
Cookies must be set before any content goes to the client. Make sure you haven't sent anything to the client before calling a setcookie as it's actually a Set-Cookie header coming back through the request.
Something as little as a space in an include file can ruin this. (You said you worked on other files, check that nothing being included has anything such as a debug echo or whitespace outside of your <?php ... ?> brackets)
As a general rule of thumb, if I have a file that is exclusively PHP code I only include the opening tag (<?php) and exempt the last one. PHP will still parse and run, but this avoids any whitespace at the end of the file that may become problematic. e.g.
mycodefile.php
<?php
define('...', ...);
function ...(){ }
Also, you mentioned using chrome. Open your debugger in chrome (ctrl+shft+i) and click the Network tab. Then find your logout call and select it, then click Headers and verify your cookie is being cleared. (likewise you can click Resources and look under Cookies to view any set.
Coles Notes version:
index.php?map_id=foo is loaded into iframe on www.not-my-domain.com. index sets SESSION['map_id'] = foo. Flash file tries to get SESSION['map_id'] thru Authenticate.php, but Authenticate.php has no values set for any SESSION varaibles.
-- Only first-load, cross domain issue.
Verbose:
I have an index while where I set: SESSION['map_id'] = foo
The index file then loads a flash file. When initialized, the flash accesses an 'Authenticate.php' file which echo's out the SESSION['map_id'] and is loaded into flash via LoadVars. Flash then displays the appropriate data.
This step cannot be done another way
This all works just fine on our main site. The issue comes when we try to port out to other sites by providing iframe embed codes:
<iframe src="http://www.mydomain.com/?map_id=foo&code=bar" ... ></iframe>
On a fresh load of the embed code from another site (www.anotherdomain.com), it seems that the SESSION variables have been destroyed, as flash simply says they are empty. ( $map_id outputs a blank )
The index file will still properly echo $map_id as 'foo', it just seems the 'Authenticate.php' file cannot access the SESSION varaibles.
I have ensured session_start() is present in all appropriate files.
PHP session ids are passed through cookies by default, but you can't transfer cookies across domains. Try passing the session id through the url instead.
Here is the appropriate page in the php documentation.
There are a few ways you can get php to pass the session id in the url if it's not being done automatically.
You can manually pass the session id in the url (must come before other get variables):
<iframe src="http://www.mydomain.com/?&map_id=foo&code=bar">
You can disable cookies, forcing every request to have the session id automatically added to the url:
ini_set("session.use_cookies","0");
You can edit the url_rewriter.tags setting, which tells PHP which html tags to rewrite with the session id. Here, iframe=src has been added to the default set:
ini_set("url_rewriter.tags", "a=href,area=href,frame=src,iframe=src,input=src,form=fakeentry");