【问题标题】:How to validate password with jquery and php?如何使用 jquery 和 php 验证密码?
【发布时间】:2012-04-25 17:14:28
【问题描述】:

我以前从未这样做过,而且我还没有在 Google 或 StackOverflow 上找到太多帮助。

这是我所拥有的:密码输入:

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

还有一些 jQuery 来检查密码:

<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>

还有一个密码分配的php页面(pass.php):

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

现在,我可以让它提醒“图形”,但我不能让它将数据与输入值匹配以检查它是否是正确的密码。

我做错了什么,以这种方式验证密码的潜在危险是什么?

【问题讨论】:

    标签: php jquery authentication passwords


    【解决方案1】:

    “AJAX”中的“A”代表异步

    调用$post 之后的代码将在$post 函数的内容之前执行。 finish 的值将始终是 jqXHR 对象,(input==data) ? true : false 的结果将被忽略。

    更清楚:

    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){
    ...
    

    您需要重新考虑密码检查的方法,或者通过在 $.post 调用之前添加以下内容来使用同步回发:

    $.ajaxSetup({async:false});
    

    或者通过使用$.ajax 并传递async: false

    jQuery.ajax({
      type: 'POST',
      url: "pass.php",
      data: { request: "opensesame" },
      success: function(result) { ... },
      async:   false
    });   
    

    【讨论】:

    • 当然。我了解发生了什么,但我不知道如何解决。
    • 风格无关的注释;这:return (input==data) ? true : false; 应该总是写成return input == data
    • “没用”是最没用的一句话。这是不可能的。
    • 我将代码更改为“pass=data”并将 if(finish) 更改为 if(input==pass) 并且它有效。谢谢@meagar
    • @meagar 你是对的。我每天贡献的两个答案的动机都是 0,这真是令人难过。如果我的同事投票支持我的答案(当应得的),就像我投票给他们的一样,那就太好了。
    【解决方案2】:

    首先要做的是清理代码,恐怕它太晦涩了。

    我会这样写:

    <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>
    

    注意事项:

    • AJAX POST 是异步的,您无法在回调中更改变量后立即检查变量,您需要在回调中处理内部的内容。
    • 必须在服务器上验证密码,而不是在 javascript 中验证!!
    • 补充上一个项目符号,不要在 javascript 中写入您的密码!

    在服务器上:

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

    注意事项:

    • 您使用isset() 来检查变量是否存在,好调用。继续做。
    • jQuery POST 需要来自服务器的 javascript 值(除非您另有说明)。
    • 这就是我的代码打印'true''false' 的原因,这在javascript 中转换为布尔值。
    • 我建议返回一个带有错误详细信息的对象,如下所示:

      <?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);
      ?>
      

    【讨论】:

    • 我正在尝试验证服务器上的密码,这就是它调用 pass.php 的原因。我正在通过 pass.php 检索密码,并尝试将其与输入值匹配。我该如何做到这一点?
    • @bozdoz 正如我所说,比较服务器上的密码,不要将其传递给客户端....否则他会知道他第二次尝试的密码。
    • 客户端没有收到密码,是吗?您可以看到它,因为我发布了 pass.php 中的代码,但其他人看不到,可以吗?
    • @bozdoz 任何人都可以通过打开 Firebug/Fiddler/Wireshark 看到它。
    • @bozdoz 检查浏览器生成的任何 AJAX 流量非常容易。请弄清楚 Firebug 是什么,它可能是您可用的最有价值的 Web 开发工具。 Firebug 将准确地向用户显示您的页面发送到服务器的内容,以及服务器的响应方式。创建表单也很简单,但比这更容易。克里斯蒂安是绝对正确的。您绝不能将您的密码发送给客户。
    【解决方案3】:

    您必须将输入字段序列化为脚本中的所有数据:

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

    只要你在自己的服务器上,我看不到太多潜在的危险,因为它发送一个普通表单无论如何都会做的 POST 请求。

    【讨论】:

    • “请求”变量是我发送给 pass.php 的东西;这工作正常(也许我根本不需要它)。这并没有回答我关于如何从 pass.php 取回密码以匹配我的“输入”变量的问题。
    • 为什么要发回密码?如果登录成功,您只需发回即可。您的 PHP 脚本(如这里的 graphics)的返回值将位于您的匿名函数中的 data 中,该函数将在请求/应答完成后自动执行。
    • 我不明白你的意思。在提交表格之前,我正在检查他们的密码是否正确;在我知道密码正确之前,我不会提交表单,但我不想将密码保存在 javascript 中,因为那是不安全的。我想将密码存储在一个 php 文件中。
    • 您似乎没有正确理解这个概念:您使用$.post 发送输入字段并检查脚本中的输入。不将任何密码发送回 javascript。发送表单与发送$.post 的原理相同
    • 您可以使用 $.post 发送和接收。在本例中,我通过 pass.php 接收密码。但是我已经接受了一个答案,我会改为将输入值发送到 pass.php 并进行身份验证。
    【解决方案4】:

    这样发送数据是非常不安全的,任何人都可以使用firebug或其他类似工具截取并读取您通过ajax发送的数据以及ajax返回的值。因此,您应该对字段进行序列化或清理,并在发送数据之前对其进行加密。

    & 检查完成后发出警报的代码将在来自 ajax 的响应之前执行(注意它是异步的),因此您将获得一个存储在完成变量中的对象。

    【讨论】:

    • 我只是想从 pass.php 中检索密码并将其与输入字段匹配。我不想提交表格。密码位于 pass.php 中;不在javascript中。
    • @bozdoz 是的,'graphics' 在你的 ajax 调用中返回(我猜是密码)&所以任何人都可以使用 firefug 或其他开发工具看到 ajax 的响应
    • 他们如何看到“图形”?如果他们检查页面,他们将能够看到“请求:'opensesame'”和页面(pass.php)。但必须张贴请求。有没有办法让 pass.php 更安全?
    • ajax发送的响应也可以被firebug/chrome dev tools/wireshark等很多工具看到。您可以发送编码数据。这将确保一些安全性。
    • 只有在发布请求变量时才会发送响应。有没有更安全的方法来限制“回声‘图形’”的触发?
    猜你喜欢
    • 1970-01-01
    • 2013-07-11
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多