I need on each page check if cookies are enabled.And use this code.
<?php
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
if(!isset($_COOKIE['COOK_CHK'])){
echo"Cookies are disabled!";
exit;
}
session_start();
?>
However on the first check it gives me false until i don't refresh the page.I include this code in each page so can not redirect every time i load the page as it reduces performance.However i want to use it even if javascript is disabled.Any suggestions?
Can you use javascript? If so, all it takes is a check at the navigator.cookieEnabled variable.
It works in most modern browsers. You can read more about it here: http://www.w3schools.com/jsref/prop_nav_cookieenabled.asp
It's not possible because Cookies are in the browser, and PHP send them when the page has render, so will be available just in the second page.
A possible way to fix this is using javascript.
If you really should do it in PHP, for some crazy reason, send all your request to a main controller and save the state using other method, for example, write a var into a file, then redirect and in the next redirections you'll know if the cookies are enabled without needed any other redirection. Example:
$file = 'cookie_fake_'.$userIP;
if( !isset($_COOKIE['COOK_CHK']) && !file_exists($file) ){
file_put_contents($file, 'dummy');
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
header('Location:/');
exit;
}
if(!isset($_COOKIE['COOK_CHK'])){
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
echo"Cookies are disabled!";
exit;
}
Then you should write something to clean old files every hour or so, of course you can use a cache layer or a database or anything like that instead of writing a file.
Edit: The previous code will be really f** up if the user enables cookies and refresh the page, now I've fixed so it works at the second time it refresh. Not perfect but... You really should do this using javascript.
Cheers.
Related
I'm writing a code to redirect to home-page after logging out. I used to use
header("Location: index.php");
but I found in some tutorial that I can use
echo "<script>location.href = 'index.php'</script>";
Now I want to know the difference between both scripts and which is better?
The first one uses PHP, and the second uses Javascript (you'd need to make sure it was echo'ed inside <script></script> tags).
The Javascript solution requires Javascript to be enables and makes the browser do a little more work than the PHP header method. I think the PHP method, header("Location: index.php"); is safer. You would just need to make sure to use die(); after the header command or else risk loading the rest of the page before the redirect can be processed.
Another consideration is that the pure php solution won't work if you've already echo'ed anything (including whitespace). So in some situations, echo "<script>location.href = 'index.php'</script>"; could be a better choice.
Like Stevish mentioned, the second one is Javascript and could be deactivated by the user, if he deactivates Javascript. With PHP the Server will do the redirect.
using JS : (in <head> tag)
<script>window.location="https://stackoverflow.com";</script>
using PHP : (in <head> tag)
header('Location: https://stackoverflow.com');
end();
Which one I should use ? or another ?
and what about using <meta>?
<meta http-equiv="refresh" content="0;url=https://stackoverflow.com"/>
Many good answers , I don't know which answer I will accept, Thanks so much
The result is same for all options. Redirect.
<meta> in HTML:
Show content of your site, and next redirect user after a few (or 0) seconds.
Don't need JavaScript enabled.
Don't need PHP.
window.location in JS:
Javascript enabled needed.
Don't need PHP.
Show content of your site, and next redirect user after a few (or 0) seconds.
Redirect can be dependent on any conditions if (1 === 1) { window.location.href = 'http://example.com'; }.
header('Location:') in PHP:
Don't need JavaScript enabled.
PHP needed.
Redirect will be executed first, user never see what is after. header() must be the first command in php script, before output any other. If you try output some before header, will receive an Warning: Cannot modify header information - headers already sent
A better way to set the location in JS is via:
window.location.href = 'https://stackoverflow.com';
Whether to use PHP or JS to manage the redirection depends on what your code is doing and how. But if you're in a position to use PHP; that is, if you're going to be using PHP to send some JS code back to the browser that simply tells the browser to go somewhere else, then logic suggests that you should cut out the middle man and tell the browser directly via PHP.
It depends on how and when you want to redirect the user to another page.
If you want to instantly redirect a user to another page without him seeing anything of a site in between, you should use the PHP header redirect method.
If you have a Javascript and some action of the user has to result in him entering another page, that is when you should use window.location.
The meta tag refresh is often used on download sites whenever you see these "Your download should start automatically" messages. You can let the user load a page, wait for a certain amount of time, then redirect him (e.g. to a to-be-downloaded file) without Javascript.
PHP redirects are better if you can as with the JavaScript one you're causing the client to load the page before the redirect, whereas with the PHP one it sends the proper header.
However the PHP shouldn't go in the <head>, it should go before any output is sent to the client, as to do otherwise will cause errors.
Using <meta> tags have the same issue as Javascript in causing the initial page to load before doing the redirect. Server-side redirects are almost always better, if you can use them.
The first case will fail when JS is off. It's also a little bit slower since JS must be parsed first (DOM must be loaded). However JS is safer since the destination doesn't know the referer and your redirect might be tracked (referers aren't reliable in general yet this is something).
You can also use meta refresh tag. It also requires DOM to be loaded.
window.location.href = 'url';
is beter than
header('location:url');
because the header command is mustly return an error "Warning: Cannot modify header information - headers already sent"
using js window.location.href = 'url';
this is beter
I have the following PHP script within a file named login.php
<?php
$ref = $_SERVER['HTTP_REFERER'];
if ($ref == 'http://example.com/dir/invalid.php' || $ref == 'http://www.example.com /dir/invalid.php') {
echo '
<div id="invalid">
TESTTESTTESTTESTTESTTESTTESTTEST
</div>
';
}
?>
I have deliberately went to the invalid.php page (which redirects using header() to login.php) and this div does not show up. Does it have something to do with the referrer not really being invalid.php or is there an issue with the script?
Thanks
I don't think the HTTP_REFERER is what you think it is. Namely, it is the page from which the user followed a link to the current page. However, it's very unreliable as we rely on the browser of the user to correctly report this value.
I would suggest the option I thought you needed, except that the only one I can think of you might doesn't really makes sense... (checking if the url matches a url that's not the current script)... so I do not see what you are trying to do.
As promised several ways to do what you want to achieve:
First off, I don't like this solution at all and really consider it ugly, but it's the one closest to what you where trying to do.
invalid.php
require 'login.php'; // we include the file instead of referring to it
login.php
if ($_SERVER['SCRIPT_NAME'] == 'invalid.php')
{
// do whatever
}
The main difference between what you did and what I did for the user will be that here the url bar will show that you're at invalid.php and not somewhere else. This also means that refreshing doesn't make the message go away.
A better solution in my opinion is the following:
In your script that logs a user in (checks the database and everything):
if (!valid_login()) // pseudo-code, obviously
{
$_SESSION['invalid_login'] = true;
header('Location: login.php');
// previously, we had something like this instead of the two lines above:
// header('Location: invalid.php');
}
in login.php
if (isset($_SESSION['invalid_login']) && $_SESSION['invalid_login'])
{
$_SESSION['invalid_login'] = false;
// do whatever
}
Of course, this should be done with proper session facilities like starting up the session in both those files. Instead of using session variables, you could include the file and use normal variables or send GET variables through the header request, but both those solutions share a problem: refreshing doesn't make the message disappear. However, if you were to move the code from the top file of the two above to login.php (if it's not already there, I don't know what file that actually is...) you could once again use normal variables instead of session variables and have a solution in which refreshing does make it go away. In this case, you might argue that you are cluttering your files with bussiness logic and presentation, but there are solutions to that (like keeping it in a separate file, and including it into login.php, moving the html to another file and including that one into login.php or both.
i've got a slight problem with JS enabled detection.
not too big, because i know i'm on the right track.
but here's my deal:
when i try to set a cookie in JS (jQuery) using this code
$(window).load(function(){
$.cookies.set('c_jsEnabled', 'true');
});
or just in plain JS using this code
function setCookie()
{
document.cookie='c_jsEnabled=true';
}
<body onload="setCookie();">
and then try to detect it in PHP using this code
if($_COOKIE['c_jsEnabled'] == 'true')
{
if(file_exists('./main.php'))
{
require_once ('./main.php');
}
echo getIndex();
}
else
{
if(file_exists('./noJS.php'))
{
require_once ('./noJS.php');
}
echo getIndex();
}
setcookie('c_jsEnabled', '');
it takes 2 page refreshes to actually get the right value into PHP.
my guess is that this bascially means that the PHP script is executed before the JS function is fired.
could this be because all codes shown above are in the same script (index.php)?
This is kind of a problem for me, because i want to prevent people from using my website when they have JS disabled.
is there a way to set the cookie before php tries to get the cookie variable?
PHP is always "fired" before JavaScript because PHP is processed on the server and then sends out the HTML and JavaScript for the browser to process and render. You can never expect JavaScript to execute before PHP for this reason.
In your case, use JavaScript to set the cookie and then do a redirect to refresh the page so PHP can get the cookie value and act accordingly.
You should be setting the cookie directly from the PHP file. That way, you know that it exists, and more importantly, you have control of the cookie. You can set it from the client, but that will always execute after the HTML has been sent to the browser, so the PHP file won't get it until the next request.
PHP only sends the cookie header when content is sent to the browser. Javascript then executes after that, so you would need a second load of the page to detect the cookie.
This can trigger infinite redirection loops (especially if the user has cookies disabled), so be careful.
To disable the site to users without Javascript, consider the following.
<div id="noscript" style="width:100%; height:100%; z-index:999; position:absoloute; top:0px; left:0px; background-color:#CC9900; display:block">
Please Enable Javascript!</div>
<script type="text/javascript">
document.getElementById('noscript').style.display = 'none';
</script>
I find the <noscript> tag is unreliable (there was a bug in iOS causing it to only show when there was Javascript, if I remember correctly).
A second option:
You can have the PHP check for a cookie. If it isn't set, have it redirect (header("Location: aaa.html");) to a page with the Javascript to set the cookie and redirect back. (Alternatively, have the PHP output Javascript to set the cookie reload the page.) You then only have to worry about users who "spoof" the cookie, although you will also lock out users who have cookies disabled.
Nope - PHP will always be called before client-side JavaScript, so with this method you'll always have to refresh the page at least once. You're better to develop your site so that non-JS users have a worse-but-still-acceptable experience, or at worst use the <noscript> HTML tag to serve alternative content to those users.
You can't get a cookie in PHP that's being set by JavaScript before the page renders/executes.
You could set the cookie using PHP, however. That will ensure it's set and available regardless of JavaScript or multiple page refreshes.
I have several pages inside an AJAX directory. I don't want these pages accessible directly so you cannot just type in the URL of the page within the AJAX directory and access it. I "solved" this by using a PHP session on the page that calls it as follows:
Main page:
<?php
session_start();
$_SESSION['download']='ok';
?>
and on the ajax page I have this:
<?php
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;}
?>
The only problem is that if a user goes through the correct process once, the cookie is stored and they can now access the page directly. How do I kill the session once they leave the parent page?
thx
why use session ?
if i understood what you want:
<?php /// Is ajax request var ?
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])=="xmlhttprequest") {
// do your ajax code
} else {
// redirect user to index.php since we do not allow direct script access, unless its ajax called
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit();
}
} ?>
A really simple solution is to open up each of the files you want to protect from direct URL entry & add the following to the top:
<?php if (isset($_GET['ajax']) != true) die();?>
Now get rid of your redirect script since it's useless now. You don't need to use sessions for this. Every time you request a page, use it's direct URL, just add ?ajax=1 to the end of it.
By adding the ?ajax=1, PHP will set a key of 'ajax' to the $_GET global variable with the value of 1. If ?ajax=1 is omitted from the URL then PHP will not set a key of 'ajax' in $_GET and thus when you check if it's set with isset() it will return false, thus the script will die and not output anything. Essentially the page will only output data if ?ajax=1 is at the end of the URL.
Someone could still "spoof" the URL and add '?ajax=1' themselves, but that is not the default behavior for people or web browsers. If you absolutely need to prevent this then it will be much more complicated, e.g. using templates outside of a publicly available folder. Most other "simple" solutions will have the same "spoofing" potential.
There's really no way to accomplish this with a 100% certainty - the problem is, both AJAX and regular web browser calls to your web site are using the same underlying protocol: HTTP. If the integrity and security of your site depends on keeping HTTP clients from requesting a specific URL then your design is wrong.
so how do you prevent people from directly accessing files inside certain directories while still letting the site use them??
Create a controller file. Send all AJAX requests to this controller.
ajax-control.php
<?php
$is_ajax = true;
include "ajaxincludes/test.php";
// ... use the ajax classes/functions ...
ajaxincludes/test.php
<?php
if (!isset($is_ajax) || !$is_ajax)) {
exit("Hey you're not AJAX!");
}
// ... continue with internal ajax logic ...
If clients try to access the file directly at http://mysite/ajaxincludes/test.php they'll get the error message. Accessing http://mysite/ajax-control.php will include the desired file.
I don't think there is a surefire way to do what you are asking, since HTTP request headers can be faked. However, you can use $_SERVER['HTTP_REFERER'] to see if the request appears to be coming from another page on your site.
If the rest of the security on your site is good, the failure of this method would not grant the user access to anything they were not already able to access.
I've never tried this but maybe you could do something with jQuery's .unload() and then call a PHP page to unset() the session.
Why not (on Ajax page):
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;
}
// do whatever you want with "access granted" user
// remove the download flag for this session
unset($_SESSION["download"]);