AJAX / PHP质询 - 响应登录

时间:2014-02-09 00:23:50

标签: php ajax authentication hash challenge-response

我已经开始研究一个新的Web项目了,这次我想我会更多地考虑如何处理用户身份验证(之前只使用MD5哈希密码)。我觉得我已经在网络的所有角落搜索了一个简单的,非过度的解决方案,现在我想知道以下是否可以实现:

  • 客户输入用户名和密码,然后按“提交”

  • 提交给服务器的AJAX请求,要求提供随机令牌/ nonce / secret / passphrase

  • 服务器将nonce返回到使用密码和nonce进行哈希的客户端

  • 客户端将用户名和哈希值(密码+ nonce)发送到进行身份验证的服务器

我的问题如下:

  1. AJAX是否可以向服务器请求一个nonce并让服务器等待哈希转回? ( async:false也许?随意提供片段/示例)我看到的唯一其他选择是将nonce存储在隐藏字段中,这似乎不太有利。

  2. 这会提供任何额外的安全级别吗?

  3. 如果没有,还有其他选择吗?我应该像以前一样以明文发送密码吗?

  4. 注意: 我知道很多人会想说HTTPS / SSL是实现安全网站的唯一方法,我听到了,但是因为这个项目不应该只有少数用户全部由我手动创建将不会有金融交易或其他敏感数据交换等安全信息我只想在登录过程中使用合理的方法来保护密码/数据。在这种情况下,MITM和所有其他威胁对我来说都不是问题 a)大多数黑客都不会对我的小型私人使用项目感兴趣 和 b)任何数据丢失或安全漏洞的计算成本不足以保证购买SSL证书

    任何意见或建议都表示赞赏(即使是那些想要骂我是一个吝啬新秀的人;)

3 个答案:

答案 0 :(得分:0)

1 - 是的是可能的。您可以发送多个AJAX请求,您可以设置一些逻辑来触发,只有在满足某些条件后才响应。也许您可以考虑在客户端使用md5或其他一些支持的技术创建随机盐。

2 - 是的,在散列敏感信息方面,任何事情都比md5更好,并且明确发送文本是彻头彻尾的麻烦。

3 - 从openwall看看phpass。它是一个易于实现的开源密码哈希框架,可以帮助您正确完成工作。一些较大的名字使用它包括wordpress等。如果你设置在ajax上,你将不得不对自己进行一些修改。

答案 1 :(得分:0)

<?php

    // this is normally where you should include a connection to you database
    // to check user input against what is stored 
    if(isset($_POST["username"])) {
        $username = $_POST['username'];
        if ($username == "Joe Schmoe") {
            echo $username.' is taken';
            exit();
        } else {
            echo $username.' is available';
            exit();
        }
    }
?>
<?php

    // this is also where you should include a connection to you database
    // to check user input against what is stored 
    if(isset($_POST["submitIt"])) {
        $username = $_POST['submitIt'];
        if ($username == "Joe Schmoe") {
            echo 'Username is taken';
            exit();
        } else {
            echo 'Success!!';
            exit();
        }
    }
?>
<!DOCTYPE html>
<html>
<head>
    <script>
        function ajaxObj(meth, url) {
            var x = new XMLHttpRequest();
            x.open(meth, url, true);
            x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            return x;
        }
        function ajaxReturn(x){
            if(x.readyState == 4 && x.status == 200){
                return true;
            }
        }
    </script>
    <script>
        function username_availability() {
            var un_value  = document.getElementById("username_value").value;
            var un_error  = document.getElementById("username_error");
            var un_status = document.getElementById("username_status");
            if (un_value != "") {
                var ajax = ajaxObj("POST", "<?php echo $_SERVER['PHP_SELF']; ?>");
                ajax.onreadystatechange = function() {
                    if(ajaxReturn(ajax) == true) {
                        un_status.innerHTML = ajax.responseText;
                    }
                }
                ajax.send("username="+un_value);
            }
        }
        function submitIt() {
            var un_value  = document.getElementById("username_value").value;
            var un_status = document.getElementById("username_status");
            var sb_button = document.getElementById("submit_button");
            var r_message = document.getElementById("result_message");
            var un_form   = document.getElementById("username_form");
            if (un_value == "") {
                un_ststus.innerHTML = "Form data is missing";
            } else {
                un_status.innerHTML = 'processing...';
                var ajax = ajaxObj("POST", "<?php echo $_SERVER['PHP_SELF']; ?>");
                ajax.onreadystatechange = function() {
                    if(ajaxReturn(ajax) == true) {
                        if(ajax.responseText == "Username is taken") {
                            un_status.innerHTML = ajax.responseText;
                        } else {
                            window.scrollTo(0,0);
                            r_message.innerHTML = 'Username is yours!!!';
                            un_status.innerHTML = ajax.responseText;
                        }
                    }
                }
                ajax.send("submitIt=" + un_value);
            }
        }
    </script>
</head>
<body>
    <form name="username_form" id="username_form" onsubmit="return false;">
        <div>Username: </div>
        <input id="username_value" type="text" onkeyup="username_availability()" autofocus>
        <button id="submit_button" onclick="submitIt()">Submit</button>
        <div id="result_message">Submit Username</div>

        <div id="username_status"></div>
    </form>
</body>
</html>

答案 2 :(得分:0)

经过大量研究并查看代码片段后,我最终意识到无论我在客户端实施什么样的保护(在Javascript中散列,请求nonce等),增加安全感只会是一种错觉。 。当然,它不会受到伤害,但我继续回到“通过默默无闻的安全”的报价。

也许有一种方法可以创建一种智能,简单的方法来验证用户身份并保护凭据而不使用HTTPS / SSL,但我无法找到它(我绝对没有编码技巧来识别它出我自己的。)

我想我会加入SSL的浪潮,为自己节省大量的时间和麻烦。