I have an index.html file which I want to run some jQuery when it is loaded. Essentially, I want to check to see if a user is already logged in based on some session variables.
So index.html will contain some jQuery which uses $(document).ready(function(){ });
In this function I want to just fire autheticate.php which checks to see if $_SESSION['user'] is set, if it is then it will redirect to home page otherwise it will redirect to login page...
how can I post in jQuery without having a html form? I just want to post to a url...
EDIT:
Based on #jondavidjohn's answer I changed my web app so that it uses index.php to check sessions:
<?php
session_start();
if(isset($_SESSION['username'])){
//go to home page
header('Location: ...home.html');
}else{
//go to login page
header('Location: ...login.html');
}
?>
It is surely possible doing this with javascript, but it is not secure at all...
You need to be checking at the server level for $_SESSION['user'] before you even send the content to the browser...
My answer would be to do the checking / redirecting with PHP before anything gets sent to the browser, it will be less complicated and more secure...
The reason a javascript solution is insecure is that you are relying on a technology that resides and is controlled by the client to control access to protected areas.
You can use $.post(url, params), where url is a string and params is a hash with your post data.
$.post("/authenticate.php",null,function(data){
// do something based on response returned
if($data){alert("authenticated");}
else
alert("not authenticated");
});
in your php file
if(isset($_SESSION['user']))
{
echo true;
}
else
return false;
Use $.post() to post data via AJAX to a page. Doing it this way won't allow the PHP script to redirect the user, you'll have to java JavaScript redirect them.
$.post('/path/to/page.php', {userID: 5}, function(data){
// Use window.location to redirect
});
Or, you can create a "fake" <form> element, and post that.
var $form = $('<form/>').attr({
method: 'post',
action: '/path/to/page.php'
});
var $input = $('<input/>').attr({
name: 'userID',
type: 'text'
}).val('5');
$input.appendTo($form);
$form.submit();
I suggest you take #jondavidjohn's advice, and have PHP redirect the user before the page is sent to the browser. That's much more secure.
Why bother with the AJAX request? Since you're building the page with PHP, just have PHP embed some variables in a JavaScript block:
<script type="text/javascript">
var is_logged_in = <?php echo $_SESSION['logged_in'] ? 'true' : 'false' ?>;
</script>
This'd save you an HTTP round-trip to retrieve data you already had available.
Related
I have a password protected website--imagine something like linkedin-- where if the session expires you are prompted to log in again.
Some pages have ajax calls, however, that load content from the server into divs.
If you come back to the open div after the session expires and try to enter something, the php on the other end does a redirect within the div, and basically loads the whole login page inside the div. This creates a page within a page, an obvious error that tells the user, the site is not working properly.
Instead of the login page appearing inside the open div, I would like the div to close and the whole page redirect to the login. I am having trouble accomplishing this, however.
Right now I am doing the password protection with an include that checks for session and either allows you to continue or bumps you out to the login page.
If ($_SESSION['login'] != '1') {
header("Location: relogin.php"); }
I have this include in the scripts triggered by ajax calls to fill divs so users cannot bypass security. It is a catchall include that also holds some global variables, functions and so forth.
Can I add code that detects if call is coming from ajax or something so as not to do redirect and instead give message to login. Or ideally, close div and redirect whole page?
Because it is a large site, I would like to find one block of code that could go into the global include.
Would appreciate any suggestions.
You will need to do the redirect on the JS side.
Let's go over the PHP side first. You want to give your AJAX handlers a clear, unambiguous, stateful response: "sorry, you're not authorized". Let's borrow from REST a bit right?
Top of each of your AJAX calls:
<?php if (!YouAreLoggedIn()) {
header($_SERVER['SERVER_PROTOCOL']." 403 Forbidden");
exit(); ?>
This will throw the visitor a 403 error, and will kill the script. 403 errors in jQuery count as a XHR error, so you can map it independently of everything else.
Your typical AJAX call then becomes:
$.ajax({
url: "your.url.here.php",
type: "POST",
success: function(d) { YourSuccessCallHere(); },
error: function() { window.location.href='your.redirect.here.php'; }
});
This is the cleanest way to do it.
You could differentiate the two different calls by User-Agent or other header fields.
Use setRequestHeader() as described in links below:
JQuery Ajax Request: Change User-Agent
http://www.w3.org/TR/2007/WD-XMLHttpRequest-20070618/#dfn-setrequestheader
You could add a GET variable to the request URL whenever you're calling it via Ajax:
myurl.php?ajax=Y
Then on myurl.php, check to see if it's an ajax call:
if(!isset($_SESSION['login']) || $_SESSION['login'] != '1') {
if(isset($_GET['ajax'])){
echo json_encode("Please login!");
exit;
}
else{
header("Location: relogin.php");
exit;
}
}
Use the following header to check if the request was an AJAX request:
X-Requested-With: XMLHttpRequest
read the header in php using:
$_SERVER['HTTP_X_REQUESTED_WITH'];
I have a web page, let's call it main.php which displays an image of football field and some players distributed on the field. However, that page uses list.php as a right side frame that loads a list of players.
What happens is, when the user clicks on a player on the field (main.php), let's say on the image of the Goal Keeper (GK), a list of GKs from world wide teams will load in right list fram (list.php). This is by using ajax.
So far we are good.
The current situation is, when session times out and the user clicks on a player from the field, the list on the right does not load, instead, list of players disappears from the list and a message says "Please login" is displayed on the right side frame (list.php)
The objective is, when session times out I want the whole website to redirect to the main page index.php
The problem is, I already put the redirecting code just before the code that is responsible of displaying the message "Please login". But what happened is, the redirection happens from within the frame, so i ended up having main.php displaying the field, and list.php displaying the main page!
Here's the code I added.
$user_id = NSession::get('user_id');
if (!isset($user_id))
{
NSession::removeall();
General::Redirect('index.php');
}
They are using Smarty. and btw, I added the same code to top of main.php, and now if user tries to access main.php without logging in, it will redirect him to the main page, so the code works!
n.b. The project is not mine, it belongs to the company I work in.
And I don't know which code is checking the session, all what I know is, if the user click on a player from the field after the session timeout, the "Please Login" message will be shown in the frame.
I'm guessing the redirect is essentially the same as using a header() function. It isn't possible to specify a target using a php redirect as it is server-side - specifying the target is client-side.
You would need to print something like this to the screen:
<script type="text/javascript">window.open('index.php','_parent');</script>
And that will redirect the user to the index.
Using frames for such purpose is... well... so 80ish...
Anyway, the frames are probably named in such a scenario. This means you can address them, but also that you have to address them. Just loading an url inside the "current" frame does exactly that, which is why your approach won't work.
If you really have to go with that frame based approach, then you will have to use javascript to address all known frames and redirect them.
Maybe you can use some javascript inside of your frame like so :
<script type="text/javascript">
window.top.location = 'YourPage.html';
</script>
Hope this helps
The issue was that the session expires while I'm on main.php. Therefore, any subsequent Ajax requested will fail since all requests requires session to be active.
the problem was that the Ajax request being sent from the IFrame (the IFrame is inside main.php and points to list.php thru Ajax calls) is failing due to session expiry.
So I've fixed this issue by adding another two session checks, one on main.php, list.php using PHP (check for session, if it's there, redirect). And in the main container, main.php, I check for the session via JS, interval Ajax requests to check the session, if session has ended, then use redirect using JS.
PHP:
$user_id = NSession::get('user_id');
if (isset($_POST["checklogin"]))//check loging
{
die(isset($user_id) ? "true" : "false");
}
if (!isset($user_id) || $user_id == "")
{
NSession::removeall();
General::Redirect('login.php');
}
JavaScript:
jQuery(document).ready(function($) {
$(window).focus(function() {
checkSession();
});
});
function checkSession()
{
$.ajax({
type: "POST",
data: {"checklogin": "cl"},
url: "list_players.php",
success: function(result) {
if (result === "false")
{
if (FIELD.showMessage === false)
{
FIELD.showMessage = true;
alert("Your session has been closed\nYou will be redirected to login page now. ");
window.location.href = ("login.php");//incase user clicks OK
}
}
}
});
}
I want to prevent user to see directly PHP URL in Javascript.
Example :
{
$.ajax(
{
type: "POST",
url: "search.php",
data: dataString,
cache: false,
success: function(html)
{
$("#display").html(html).show();
}
});
}return false;
Is it possible or any way to prevent user see the php URL when He/She view the source of my page ? Sometimes user maybe try to open the php url directly.
Thanks for helps.
I (or any client) can still use any number of tools to figure it out (including the built-in debugger in 99% of the browsers built)--It's not worth obfuscating it.
If you're concerned about direct access, check for an AJAX request in your script. (Still hack-able, but it's a start). As also provided in a previous answer:
<?php
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
if (!$isAjax) die('Unauthorized access');
/* rest of search.php */
As stated in comments,
How can We prevent the User open directly the PHP url ?
You should create a session of very long random string (token) in your php and pass it to the js ajax function, so that it sends the token along with the ajax request. On server side you can check if its the same token generated. You may want to expire the token soon.
I dont know, if its the standard way, but can provide you a start.
Ok to make things clear..
Once its on the client-side(the browser) you can't hide it. Users can still download or view source the client-side return.
Obfuscating is not really needed because you just make things complicated and not protecting anything.
But anything that is server-side code(PHP) will not be shown as it is processed by the server-side and the server just return the results of execution of the server-side code.
well in case of your problem the thing you can do is to check whether the $_POST and $_GET parameters are valid upon reaching your PHP codes thus making every POST and GET request valid and safe. its somewhat like this
<?php
if(isset($_POST['username']) && isset($_POST['password'])){
//everything seems fine
echo 'ok';
}
else{
//someone is doing a direct acess
header('index.php');
}
?>
or check the sessions to protect your pages only for logged-in users
<?php
if(isset($_SESSION['userid'])){
//everything seems fine
echo 'ok';
}
else{
//someone is doing a direct acess
header('index.php');
}
?>
I have this simple login script:
$.ajax({
type: 'POST',
url: 'authorize.php',
data: { username: user, password: pass },
dataType: 'json',
success: function(data) {
if (data.status == "loggedIn") {
//Logged in
} else {
//Not logged in
}
}
});
Where //Logged in is, how should I call the page that required the login? I could simply $.load the page, but then what was the point of verifying a login when the user could just browse to this file in the first place?
I'd suggest using PHP Sessions across all of these pages. Make a check on the page you're going to $.load that the user is actually logged in and set the user as logged in on the authorize.php page if successful.
This way, if a user looks at the page source and see's what you're loading, but when they try and access that page it won't do anything because you're checking to see if they've been logged in already.
It's a matter of presentation, you can just load a div on another file, you don't need to load the whole thing.
I use ajax to login and $.load to "bring" a div I have in a template file. It's just because it makes it easier when you need to change the design.
Remember that splitting the work into individual "pieces" makes it easier for you to change things. Imagine you have the same login box on 20 individual templates. If you change one, you have to change 19 more.
You can't prevent a user from doing anything with javascript (jquery), since it is client-side and easily disabled/changed etc.
What you can do is simply $.load the page like you say, but also have a check against the session on the loaded page that checks for an actual login before sending the content. You'd need to set some variable in the session as part of authorize.php to indicate a successful login.
To prevent data from being accessed, you should look into using .htaccess and Apache's mod_rewrite. Whenever a user requests a piece of possibly sensitive data, you'll invisibly call a PHP page which will then serve up either the requested data or a 403 Forbidden.
Example:
.htaccess
RewriteEngine On
RewriteRule ^user-content/(.+) display_content.php?file=$1
Then, any files that would be accessed in user-content will be rerouted through display_content.php. You can also use this .htaccess file to help prevent hotlinking by refusing to display the resource if there's a referrer.
display_content.php
<?php
if (isLoggedIn($_COOKIE["username"], $_COOKIE["password"]) && isset($_GET["file"])) {
if (mimeTypeOk($_GET["file"]) { // Implementation not shown
readfile($_GET["file"]);
exit();
}
}
header("403 Forbidden");
?>
In order to do this the most secure way, you are going to have to use both jQuery as a client-side way and PHP as a server-side way of checking if the user is logged in. You don't need to load the entire page with jQuery, just use the following code to load only a div portion:
$("#load_dom").click(function(){
$("#result")
.html(ajax_load)
.load(loadUrl + " #picture");
});
Then, as a security measure, use PHP to restrict access to the page, by checking $_SESSION vars like this:
if (!isset($_SESSION['userid'])) {
// user is logged in
} else {
// user is not logged in
die("You are not logged in.");
}
i have a jquery Ajax request happening on a page. On php side i am checking if the session is active and doing something. If the session is not active i want to redirect the user to another page in php(header redirect). how do i do it.
I know how to achieve it in javascript(i.e if session_fail then change window.location but is there something that i can do in php/cakephp
Redirects only say "The data you requested can be found here".
HTTP provides no way to say "Even though you requested a resource to go inside a page, you should should leave that page and go somewhere else".
You need to return a response that your JavaScript understands to mean "Go to a different location" and process it in your own code.
If I understand what you want to happen then this is how I'm implementing it. It's in Prototype instead of jQuery but it shouldn't take you long to translate:
new Ajax.Request('process.php', {
on401: function(response) {
var redirect = response.getHeader('Location');
document.location = redirect;
}
});
In your PHP, output the following if the session is inactive:
header('Location: http://example.com/login.php', true, 401);
exit;
This is what you would want in your php IF THIS WERE A REGULAR REQUEST, NOT AN AJAX
if (isset($_SESSION)) doSomething();
else header("Location: otherUrl");
Since this is an Ajax call, you are not passing control to the php, but just trying to get a response that (likely) fills a particular section of your page. You do not mention what jQuery ajax function you use, but it matters. I would imagine you are using either $.get() or $(element).load() ??
Without knowing the particulars, this is my best suggestion for you.
Ajax call: $.get(url, callbackFunc);
php:
if(isset($_SESSION)) echoSomething() else echo("redirect");
callbackFunc:
function(data)
{ if (data == "redirect") window.location = otherUrl;
else
$("#desiredElement").html(data);
}