实现会话以保持用户记录,安全问题

时间:2013-07-02 08:09:44

标签: php javascript html security

以下问题是一个安全问题。 只要浏览器处于打开状态,我就会使用Sessions让用户登录我的网站。

现在我保持用户登录的php代码非常简单。 当用户登录时,我首先使用用户名创建会话(authentication.php):

if (($row['user'] == $usr)&&($row['value'] == $pwd)) {
    $response = "ok";
    session_start();
    $_SESSION['name'] = $usr;
    break;
}

然后我从每个页面创建一个JavaScript调用来检查用户是否存在我更改了网页(AJAX) 看起来好像是用户被记录(在标题欢迎中显示),JavaScript看起来像这样:

function checkUserExistance(data,size)
{
    var xmlhttp;

    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    } else {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            var response = xmlhttp.responseText;           
            document.getElementById("title").value = response;
        }
    }

    xmlhttp.open("POST",url + page,true);

    xmlhttp.send();
}

现在在serer端检查用户是否已登录我使用以下简单函数,JavaScript正在调用:

session_start();
if (isset($_SESSION['user'])) {
    echo $_SESSION['name'];
}
现在我的问题很简单就是这样的正确方法呢?只要浏览器打开就保持用户身份验证,因为如果我做对了,JavaScript就在客户端,这意味着每个人都可以更改它并跳过检查服务器端发布评论页面。

我的解决方案是在发布评论时添加另一个检查是在服务器端检查用户是否有开放会话但是用户可以假装是另一个已经过身份验证的用户,这太令人沮丧....我是什么?我不知道该怎么办?

1 个答案:

答案 0 :(得分:2)

虽然您可能希望在生产中使用已建立的安全框架,但如果您正在尝试理解经典安全会话管理的原则,那么您的理解并不遥远。重要的是检查站点中每个页面顶部的会话数据,以确保用户没有跳过登录检查。

从用于管理会话的服务器发回的cookie将保存在浏览器的内存中。在从任何页面发送任何用户内容之前,首先要检查用户是否已登录(在会话变量中是否有用户名)。如果为空,则用户未登录,因此您将其发送到登录页面,询问其用户名/密码组合;

enter image description here

请记住,服务器内存中保存的会话状态对于进程回收不具有弹性,也不会在负载均衡的Web场上按预期工作。

任何类型的后续浏览器请求,XMLHTTP,HTML,JPG都将包含此cookie,您可以在服务器端使用该cookie来检查会话。因此,您在此处所做的工作将起作用,例如服务器使用cookie来占用您的会话。只要您的cookie不可“猜测”,这主要是用户名/密码验证系统的工作方式。

enter image description here

除非你想让会话保持更长时间,否则你不需要对XMLHTTP做任何事情。通常,服务器将在几分钟后(可配置)使cookie过期。

总而言之,对于一个穷人的安全系统而言;

  1. 每个浏览器请求,检查$ _SESSION ['user'],如果它是空的直接登录页面。
  2. 在登录页面上,检查用户名/密码匹配(读者的练习:))如果是,请在会话中存储用户名(将自动返回cookie)
  3. 基本上就是这样。浏览器cookie将每次发送,只要您每次收到请求时都不会忘记检查,那么您将很高兴。这个以及许多其他原因是为什么使用框架是好的,但我认为在这里理解基础知识是有用的。

    要记住的其他事项;

    首先,您应该只检查服务器端的安全性。你不能在客户端javascript中执行此操作。其次,您需要为每个请求和每个请求执行此操作。浏览器每次都会发送一个cookie,只要它匹配一个会话变量,你检查了早期好的用户/密码。如果没有cookie,或者cookie所涉及的会话变量不包含您之前设置的用户变量,则用户不会登录,您应该再次将它们重定向到登录页面。您可以为每个请求执行此操作。

    请记住,您的AJAX调用仍然是一个请求,因此也必须在服务器端进行相同的登录检查。最简单的方法是在PHP中设置页面标题而不是在客户端javascript中设置页面标题,但是如果你想让它成为ajax客户端,那么你需要处理服务器因上述原因拒绝你的请求的可能性。并将您重定向到登录页面将不是您对XMLHTTTPRequest的期望。因此,至少您需要更复杂的错误处理,最多只能将您的登录过程重写为仅AJAX。

    这是服务器的一些伪代码;

    if session(name) is empty then
        if IsAjaxRequest then
            send ajax access denied response code and exit
        else
            redirect browser to login page
        endif
    else
        if IsAjaxRequest then
             send ajax data // eg. title
        else
             send html page (injecting session(name) into title)
        endif
    endif
    

    那就是说。我不会写那个伪代码。我会使用不同的端点(页面)来提供浏览器HTML响应和AJAX API响应,但希望您能够全面了解您的选择。