AJAX/PHP挑战响应登录

AJAX/PHP挑战响应登录,php,ajax,authentication,hash,challenge-response,Php,Ajax,Authentication,Hash,Challenge Response,我已经开始从事一个新的web项目,这次我想我应该更多地考虑如何处理用户身份验证(以前只使用MD5哈希密码)。我觉得我已经搜索了网络的各个角落,寻找一个简单、不过分的解决方案,现在我想知道是否可以实现以下内容: 客户端输入用户名和密码并按“提交” 提交时,会向服务器发出AJAX请求,请求随机令牌/nonce/secret/passphrase 服务器将nonce返回给客户端,在客户端使用密码和nonce进行哈希 客户端将用户名和哈希(密码+nonce)发送到进行身份验证的服务器 我的问题如下:

我已经开始从事一个新的web项目,这次我想我应该更多地考虑如何处理用户身份验证(以前只使用MD5哈希密码)。我觉得我已经搜索了网络的各个角落,寻找一个简单、不过分的解决方案,现在我想知道是否可以实现以下内容:

  • 客户端输入用户名和密码并按“提交”

  • 提交时,会向服务器发出AJAX请求,请求随机令牌/nonce/secret/passphrase

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

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

我的问题如下:

  • AJAX是否可以向服务器请求一个临时值,并让服务器等待散列传输回来?(async:false-maybe?请随意提供代码片段/示例)我看到的唯一其他选择是将nonce存储在隐藏字段中,这似乎不太有利

  • 这会提供任何额外的安全级别吗

  • 如果没有,还有什么其他选择?我应该像以前那样以明文形式发送密码吗

  • 注: 我知道很多人会说HTTPS/SSL是实现安全站点的唯一方法,我听到了,但是,由于这个项目不应该有超过一小部分的用户都是由我手动创建的,并且不会有像金融交易或其他敏感数据这样的安全信息交换,所以我只希望在登录期间有一个合理的方法来保护密码/数据。在本案中,MITM和所有其他威胁对我来说都不是问题,因为 a) 大多数黑客都不会对我的小型私人项目感兴趣 和 b) 任何数据丢失或安全漏洞的计算成本都不足以保证购买SSL证书


    任何意见或建议都非常感谢(即使是那些想斥责我是个吝啬的新手的人)

    1-是的是可能的。您可以发送多个AJAX请求,您可以通过一些逻辑设置这些请求,以便在满足某些条件后触发和响应。也许你可以考虑用MD5或其他支持的技术在客户端创建一个随机的盐。 2-是的,在散列敏感信息和发送明文方面,任何东西都比md5好,这是彻头彻尾的麻烦

    3-从露天墙查看phpass。它是一个易于实现的开源密码哈希框架,可以帮助您正确完成工作。一些较大的名称使用它,包括wordpress等。如果您使用ajax,您必须自己进行一些修改。

    
    
    <?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>
    
    函数ajaxObj(meth,url){ var x=新的XMLHttpRequest(); x、 打开(meth、url、true); x、 setRequestHeader(“内容类型”、“应用程序/x-www-form-urlencoded”); 返回x; } 函数ajaxReturn(x){ 如果(x.readyState==4&&x.status==200){ 返回true; } } 函数用户名\u可用性(){ var un_value=document.getElementById(“username_value”).value; var un_error=document.getElementById(“username_error”); var un_status=document.getElementById(“用户名_status”); 如果(un_值!=“”){ var ajax=ajaxObj(“POST”,“POST”); ajax.onreadystatechange=函数(){ if(ajaxReturn(ajax)=true){ un_status.innerHTML=ajax.responseText; } } 发送(“用户名=”+un_值); } } 函数submitt(){ var un_value=document.getElementById(“username_value”).value; var un_status=document.getElementById(“用户名_status”); var sb_button=document.getElementById(“提交按钮”); var r_message=document.getElementById(“结果_message”); var un_form=document.getElementById(“用户名_form”); 如果(un_值==“”){ un_stus.innerHTML=“缺少表单数据”; }否则{ un_status.innerHTML='正在处理…'; var ajax=ajaxObj(“POST”,“POST”); ajax.onreadystatechange=函数(){ if(ajaxReturn(ajax)=true){ if(ajax.responseText==“用户名已获取”){ un_status.innerHTML=ajax.responseText; }否则{ 滚动到(0,0); r_message.innerHTML='用户名是你的!!!'; un_status.innerHTML=ajax.responseText; } } } 发送(“submitt=“+un_值”); } } 用户名: 提交 提交用户名
    经过大量研究和查看代码片段,我最终意识到,无论我在客户端实现了什么样的保护(Javascript哈希、请求nonce等),增加安全性的感觉都只是一种幻觉。当然,这不会有什么坏处,但我继续回到“通过默默无闻的安全”这句话

    也许有一种方法可以创建一种智能、简单的方法来验证用户并保护凭据,而不使用HTTPS/SSL,但我一直无法找到它(而且我自己肯定没有编码技能来解决这个问题)


    我想我会赶上SSL的潮流,为自己节省大量的时间和麻烦。

    1-你知道这方面的任何例子吗?或者PHP和AJAX se有专门的术语吗