Apologies if this question duplicates some other question, but I can't find one exactly like it in S.O.
I am writing a remotely hosted app, the kind that runs when you put a javascript on your own website page, where the src="some remote javascript.js". so, the script operates by calling every operation as a jsonp ajax. A lot of jsonp housekeeping, but otherwise works surprisingly well.
In the main remote js script, I set a user cookie when the user logs in. It works fine, the cookie is set for a year, and when you return to the page it continues recognizes you.
However, when I try to output the cookie (even after it has been set) using php, my php code does not see it for some reason.
If I alert(document.cookie); the cookie is displayed.
If I do a var_dump($_COOKIE); php returns array(0) { }.
This isn't a "you have to reload the page after setting the cookie with javascript" problem.
As far as I know, when I use the Firefox Web Developer extension to View Cookie Information, it is all happening on the same domain.
Looking over many other examples, it is clear that PHP should be able to read a cookie, even if set by javascript.
Even as I write this, I think a glimmer of what the problem is is starting to form in my head, that (possibly) a JSONP'd php script isn't going to see the cookie set by javascript.
Related
Background:
I'm developing a website tracker using javascript. Here's how it works:
1) A user visits any domain the tracker script is on "anydomain.com". The script makes a successful ajax call in the background to my master domain "masterdomain.com".
2) When "masterdomain.com" receives a request, the following PSEUDO code is run. It works by checking for an existing session and if one doesnt exist it creates a new one.
The first call appears to be fine because I am able to receive a session ID in a response. However, each successive call to "masterdomain.com" creates a new session. AKA the server doesn't find the "should be" existing session.
Sample PSEUDO Code:
if(session exists)
{
// update timestamp for session
}
else
{
// set a new session for visitor
}
// load template
api(array("accepted"=>session_id),callback);
Some Quick Facts:
1) This does not appear to be a same origin issue (as I am able to communicate with the server fine).
2) I have tried this with cookies/sessions both appear to not be working.
3) I am using codeigniter (sessions are set not to expire on page close). I have also tried using/not using database sessions).
This problem can also be solved if there is another way to uniquely identify a user each time a page loads on a server (not using IP).
Any help would be greatly appreciated as I'm about ready to tear the rest of my hair out of my head!!!! :(
This answer is incomplete in that you'll have to do some additional research, but the easiest way (which is not actually particularly 'easy') to do this is to use Javascript to place a hidden iframe to masterdomain.com, and set up iframe communication (e.g. using postMessage) to retrieve the session from that iframe to your page.
With AJAX calls you can only send/set session cookies if the URL you're calling is on the same domain as your calling script. I think you should create an iframe, call ajax from within and it should work fine. By the way, I have no idea what you are trying to track.
For some reason I need to process PHP behind the scenes but not using AJAX (I know that might sound silly to you). I need this since I am getting the content dynamically through another page loading.
By using PHP's curl functions I can get the login page of a website inside my 1.php file. But then I use javascript to set form values and hit login and it takes me to the site url (not already localhost/1.php). So the question is: I need to somehow store the content of the page that I am redirected and retrieve it .
The impression i got was that, you have a resource intensive process, which would perform some action in background , while user still interacts whit the page.
I actually would make more sense to do this with some sort of service ( as shell script or standalone application ), but it is possible to do with php: you would need to fork [1] [2] the process. Just don' forget to check, if one such process is already running on the system.
It actually works pretty well in combination with XHR (also know as AJAX by marketing department), because you can kick off the process with a request, and then repeatedly check the status .. and then collect the data, when status is "done".
Since we're all taking stabs in the dark, here's what I think you're trying to do (let me know if I'm way off):
You have a site (let's call it userfriendly.org) and you are trying to add an interface of some kind to another site (we'lll call this site mean-corp.com). Essentially, when you load the page, you use curl to fetch some of the data from mean-corp.com so that your users can login and get some info but without having to deal with their site (maybe it's ugly, maybe it just fits really well into your site, whatever).
You are able to get to the site okay to get whatever initial data you need, but when you try to pass in the user login and password to actually get their info, it's redirecting back to the login URL for the site.
Long story short, you are trying to make a front-to-back web service for another site, but you're running into hiccups with redirects and whatnot?
Am I totally off? If not, I've made similar attempts in the past for my own nobel reasons,and I could pass along some tips as I'm sure others can.
But if I'm totally off, sorry for the distraction.
after searching (and testing) a way to offer a kind of go-back button I am asking that question here (maybe there is an easy solution).
I have a description about orienteering on my website (5 pages): http://www.uhebeisen.net/o-def/o-definition_ge.php
There are many websites from abroad having a link to this pages. Now I'd like to get their URL if a websurfer is entering my pages. Then I can place a button go-back to my navigation list that brings him back to his page from where he clicked the link to my description-pages.
I've seen solutions using javascript:history.go(-1) or $_SERVER['HTTP_REFERER'] with PHP but problem is that a websurfer can move around my pages and if finishing his reading from any page should be provided with his (calling) URL, e.g. the one of his University.
So I need to catch his URL and store it in a safe place until he decides to leave. And if he returns to the starting page while surfing on my pages his URL shouldn't be overwritten.
Since I do not program - just copy&paste and try to understand what happens. Any suggestion on how this can be done is welcome.
thank you George, that one worked
I wasn't aware to place the session_start at the very beginning of the file that's why I get the two warnings.
While testing this function I found that the session variables were not always cleared by the browser. Especially with Firefox, it keeps the calling URL almost forever (WinXP, FF 5.x) whereas Firefox 5 on the Mac, Safari (Mac) and Camino (Mac) work as expected: after restarting the program I can test successfully with another website.
Does Firefox have different setting possibilities in regard of sessions than other browsers?
You should store $_SERVER['HTTP_REFERER'] in the user's session upon arrival. Using this method, the value won't be overritten when the user browses within your site.
session_start();
if ( !isset( $_SESSION['referrer'] ) ) {
if ( !empty( $_SERVER['HTTP_REFERER'] ) ) { // Because not all browsers set this
$_SESSION['referrer'] = $_SERVER['HTTP_REFERER'];
}
}
One way to do it would be to store somewhere (perhaps in a cookie or session, which easy to do with your PHP page) the page they're coming from, but only if that page is not on your website's domain. This would require some if-statements to set the cookie/session value appropriately, but it can be done relatively easily using particular parts of the referrer variable. There is probably a more efficient way to store this, but this is one that jumps to mind right away.
EDIT: I highly recommend George's solution, much better way to do this.
Have you tried using a session?
session_start();
if( !isset($_SESSION['refer']) )
{
$_SESSION['refer'] = $_SERVER['HTTP_REFERER'];
}
then, once your ready to make the button, set the link to $_SESSION['refer'].
In my past projects I usually stores the redirect url following this process:
search for a query string parameter url (www.yoursite.com/?redirect_url=my_encoded_url)
If search at point 1 doesn't return any results, then I checks for the HTTP_REFERER
In both cases, I stores that value in a SESSION variable after verified that the url belongs to my site's domain.
How to make sure a human doesn't view the results from a PHP script URL?
Recently when viewing the source of a site that was making an AJAX call, I tried to follow the link in the browser
www.site.com/script.php?query=value
Instead of getting the result I expected to see, I saw a message stating only scripts should view that page.
How do you restrict a script to only allowing a script to access it?
UPDATE:
here is the page DEMO page
Short answer: you can't.
Long answer: You can make it harder to do it by requiring special header values in the HTTP request (setting Accept to application/json is a common one). On the server side just check to make sure that header is set to the value you expect. This will make it so that regular users will get the message you mention and your scripts will work just fine. Of course advanced users will be able to easily work around that sort of limitation so don't rely on it for security.
with php you can check for and only display results if the page is called via ajax
function isAjax() {
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'));
}
if(isAjax()) {
// display content
} else {
// not ajax, dont show
echo 'Invalid Request';
}
You can't. A human being can always spoof the request. You can send your request with a post variable, to make sure a human doesn't end up on the page by accident.
One possible solution is to check the HTTP Request for it's origin.
Another solution is to send a "password" with every request. Take a look into this tutorial how to do this.
But it's never 100% secure, it only makes it harder for possible intruders.
As Tim stated, this script is almost certainly looking for this request header, which is being sent with each request to rpc.php (found via the net panel in firebug, naturally):
X-Requested-With : XMLHttpRequest
As to cross-browser compatibility, the setRequestHeader method appears to be available with both the activex and xmlhttprequest connections so this should work in all major modern browsers.
If you are calling the script by AJAX, then it MUST be accessible for you because an AJAX call is similar to your browser actually asking for the page, thus it is not only script accessible but accessible to anyone.
If it was actually called by PHP or by some other means, you could "maybe" use Apache rules or PHP scripting to diminish the accessibility.
You could set a secret value into the php session with the 'view' script and check for it with the ajax scripts.
Request 'index.php' with the
browser.
PHP builds the page, saves a key into
the session, sends the content back
to the browser.
The browser gets the page content and
makes some ajax request to your site.
Those ajax scripts also have access
to the same session your main page
did, which allows you to check for a
key.
This insures only authenticated browsers are allow to make the ajax requests.
Don't count on the ajax request being able to write to the session though. With many requests being satisfied at the same time, the last one in will be the last one written back to your session storage.
http://us.php.net/manual/en/book.session.php
A lot of open source applications use a variation of this on top of every php file:
if (!defined('SOMETHING')) {
die('only scripts have direct access');
}
Then in index.php they define SOMETHING:
define("SOMETHING", "access granted.");
edit: I'm not saying this is a good approach btw
edit2: Seems I missed the part about it being an ajax request. I agree in this case this isn't a solution.
I've to admin a small website for my alumni group which is hosted by my ISV. The url is something like www.myIsv.com/myWebSite/ which is quite ugly and very forgetable. The main admin of the webserver has registered a domain name www.mysmallwebsite.com and put a index.html with this content:
<html>
<head>
<title>www.mysmallwebsite.com</title>
</head>
<frameset>
<frame src="http://www.myIsv.com/myWebSite/" name="redir">
<noframes>
<p>Original location:
http://www.myIsv.com/myWebSite/
</p>
</noframes>
</frameset>
</html>
It works fine, but some features like PHP Session variables doesn't work anymore! Anyone has a suggestion for correcting that?
Edit:
This doesn't work both on IE and on Firefox (no plugins)
Thanks
Sessions are tied to the server AND the domain. Using frameset across domain will cause all kind of breakage because that's just not how it was designed to do.
Try using apache mod rewrite to create a "passthrough redirection", the "proxy" flag ([P]) in the rule is the magic flag that you need
Documentation at http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html
What do you mean?
Are you saying that when you go from www.mysmallwebsite.com to www.myIsv.com/myWebSite/ then the PHP session is lost?
PHP recognizes the session with an ID (alpha-numeric hash generated on the server). The ID is passed from request to request using a cookie called PHPSESSID or something like that (you can view the cookies a websites sets with the help of your browser ... on Firefox you have Firebug + FireCookie and the wonderful Web Developer Toolbar ... with which you can view the list of cookies without a sweat).
So ... PHP is passing the session ID through the PHPSESSID cookie. But you can pass the session ID as a plain GET request parameters.
So when you place the html link to the ugly domain name, assuming that it is the same PHP server (with the same sessions initialized), you can put it like this ...
www.myIsv.com/myWebSite/?PHPSESSID=<?=session_id()?>
I haven't worked with PHP for a while, but I think this will work.
Do session variables work if you hit http://www.myIsv.com/myWebSite/ directly? It would seem to me that the server config would dictate whether or not sessions will work. However, if you're starting a session on www.mysmallwebsite.com somehow (doesn't look like you're using PHP, but maybe you are), you're not going to be able to transfer session data without writing some backend logic that moves the session from server to server.
Stick a session_start() at the beginning of your script and see if you can access the variables again.
It's not working because on the client sessions are per-domain. All the cookies are being saved for mysmallwebsite.com, so myIsv.com cannot access them.
#pix0r
www.myIsv.com/myWebSite/ -> session variable work
www.mysmallwebsite.com -> session variable doesn't work
#Alexandru
Unfortunately this is not on the same webserver
What browser/ ad-on do you have? it may be your browser or some other software (may be even the web server) is blocking the sessions from http://www.myIsv.com/myWebSite/ working from with-in the frame, as its located on a different site, thinking its an XSS attack.
If the session works at http://www.myIsv.com/myWebSite/ with out the frame you could always us a redirect from http://www.mysmallwebsite.com to the ugly url, instead of using the frame.
EDIT:
I have just tried your frame code on a site of mine that uses sessions, firefox worked fine, with me logging in and staying loged in, but IE7 logged me straight out again.
So when you place the html link to the ugly domain name, assuming that it is the same PHP server (with the same sessions initialized), you can put it like this ...
www.myIsv.com/myWebSite/?PHPSESSID=<?=session_id()?>
From a security point of view, I really really really hope that doesn't work
You could also set a cookie on the user-side and then check for the presence of that cookie directly after redirecting, which if you're bothered about friendly URLs would mean that you don't have to pass around a PHPSESSID in the query string.
When people arrive # www.mysmallwebsite.com I would just redirect to http://www.myIsv.com/myWebSite/
<?php header('Location: http://www.myIsv.com/myWebSite/'); ?>
This is all I would have in www.mysmqllwebsite.com/index.php
This way you dont have to worry about browsedr compatibility, or weather the sessions work, just do the redirct, and you'll be good.