2

I've never done this before, and I haven't found much help on Google or StackOverflow yet.

Here's what I have: A password input:

<input type="text" placeholder="password" name="pass" id="password" />

and some jQuery to check the password:

<script>
$('form').submit(function(){
input = $('#password').val();
var finish = $.post("pass.php", { request: "opensesame" }, function(data) {
   return (input==data) ? true : false;
});
if(finish){
alert('sent');
}else{
alert('not sent');
}
return false;
});
</script>

And a password-dispensing php page (pass.php):

<?php
if(isset($_POST['request'])&&$_POST['request']=="opensesame"){
echo 'graphics';
}
?>

Now, I can get it to alert 'graphics', but I can't get it to match the data with the input value to check if it's the right password or not.

What am I doing wrong, and what are the potential dangers to authenticating a password in this way?

4 Answers 4

5

The "A" in "AJAX" stands for asynchronous.

The code after you call $post will execute before the contents of the $post function. The value of finish will always be a jqXHR object, the result of (input==data) ? true : false will be ignored.

More clearly:

var finish = $.post("pass.php", { request: "opensesame" }, function(data) {
   // THIS EXECUTES SECOND, and the return value is discarded
   return (input==data) ? true : false;
});

// THIS EXECUTES FIRST, with finish set to a jqXHR object
if(finish){
...

You need to rethink your methods of password checking, or use synchronous postbacks by adding the following before your $.post calls:

$.ajaxSetup({async:false});

Or by using $.ajax and passing async: false:

jQuery.ajax({
  type: 'POST',
  url: "pass.php",
  data: { request: "opensesame" },
  success: function(result) { ... },
  async:   false
});   
Sign up to request clarification or add additional context in comments.

7 Comments

Absolutely. I understand what is happening, but I don't know how to fix it.
An unrelated note on style; this: return (input==data) ? true : false; should always be written as return input == data.
"Didn't work" is the least helpful thing ever said. It's impossible to work from that.
I changed the code to "pass=data" and changed if(finish) to if(input==pass) and it worked. Thanks @meagar
@meagar You're right. It's just sad to get 0 motivation for the two answers I contribute per day. Would be nice if my colleagues vote for my answers (when deserved) just as I do with theirs'.
|
4

The first thing to do would be to clean up the code, it's too obscure, I'm afraid.

I'd write it as follows:

<script>

$('form').submit(function(event){
    event.preventDefault(); // stop the form from submitting
    var passwd = $('#password').val();
    var finish = $.post("pass.php", { request: passwd }, function(data) {
        if(data){
            alert('Success!');
        }else{
            alert('Failure :(');
        }
    });
});

</script>

Things to note here:

  • AJAX POST is asynchronous, you can't check for a variable right after changing it in the callback, you need to process stuff inside the callback.
  • You must verify the password on the server, not in javascript!!
  • Adding to the previous bullet, don't write your password inside the javascript!

And on the server:

<?php

    if(isset($_POST['request']) && $_POST['request']=="opensesame"){
        echo 'true';
    }else{
        echo 'false';
    }

?>

Things to note here:

  • You used isset() to check for the existence of the variable, good call. Keep doing it.
  • jQuery POST expects a javascript value from the server (unless you tell it otherwise).
  • This is why my code prints either 'true' or 'false', this translates to a boolean value in javascript.
  • I would advise returning an object with error details, such as the one below:

    <?php
        $result = array('success'=>false, 'reason'=>'Unknown error.');
        if(isset($_POST['request'])){
            if(trim($_POST['request'])!=''){
                if($_POST['request']=='opensesame'){
                    $result['success'] = true;
                    $result['reason'] = 'Welcome home!';
                }else $result['reason'] = 'Password is wrong';
            }else $result['reason'] = 'Password must not be empty';
        }else $result['reason'] = 'Expected parameter "request"';
        echo json_encode($result);
    ?>
    

11 Comments

I am trying to verify the password on the server, that's why it is calling pass.php. I am retrieving the password via pass.php, and trying to match it with the input value. How do I accomplish this?
@bozdoz As I said, compare the password on the server, do not pass it to the client....otherwise he will know the password the second time he tries it.
the client doesn't receive the password, do they? You can see it because I posted the code from pass.php, but someone else couldn't see that could they?
@bozdoz Anyone can see it by opening Firebug/Fiddler/Wireshark.
@bozdoz It's trivially easy to inspect any AJAX traffic your browser is generating. Please figure out what Firebug is, it is probably the most valuable web development tool available to you. Firebug will show users exactly what your page is sending to the server, and exactly how the server responds. Creating a form is also trivial, but it's even easier than that. Christian is absolutely right. You must never send your password to the client.
|
2

You have to serialize your input fields to all the data to your script:

$.post("pass.php", { request: $('form').serialize() }, function(data) { 
// ...

As long as you are on your own server I don't see much potential dangers, as it sends a POST-request which a normal form would do anyway.

6 Comments

The 'request' variable is something I am sending to pass.php; and that is working fine (maybe I don't need it at all). This does not answer my question as to how I can get the password back from pass.php to match with my 'input' variable.
Why would you send back the password? You just send back if it was a successful login. The return from your PHP script (like here graphics) will stand in data in your anonymous function, which will be automatically be executed after the request/answer is done.
I don't understand what you mean. I am checking to see if their password is correct before I submit the form; I am not submitting the form until I know that the password is correct, but I don't want to keep the password in javascript, because that is insecure. I want to store the password in a php file.
It seems you don't understand this concept right: You send your input field with $.post and check the input in your script. Not sending back any password back to the javascript. And sending a form is the same principle as doing a $.post
You can send and receive with $.post. In this example, I was receiving the password via pass.php. But I have accepted an answer, and I will instead send the input value to pass.php and authenticate it then.
|
1

Its quite unsafe to send data like this, anyone can intercept and read the data which you send by ajax and the value returned by ajax using firebug or other such tools. So you should serialize or sanitize the fields and also encrypt the data before sending them.

& the code to alert after checking finish will be executed before the response comes from ajax (note that it is asynchronous) thus you would get an object stored in the finish variable.

7 Comments

I am only trying to retrieve the password from pass.php and match it with the input field. I am not trying to submit the form. The password is located in pass.php; not in javascript.
@bozdoz yeah, 'graphics' is returned in your ajax call (I guess its the password) & so anyone can see the response of ajax with firefug or other developer tools
How can they see 'graphics'? If they inspect the page, they will be able to see "request: 'opensesame'" and the page (pass.php). But the request has to be posted. Is there a way to make pass.php more secure?
The response sent by ajax can also be seen by firebug/chrome dev tools/wireshark and many other tools. You could send encoded data. It would ensure some security.
The response is only sent if the request variable is posted. Is there a more secure way to limit the "echo 'graphics'" from firing?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.