Php 更正未授权访问和禁止访问的HTML状态代码。(使用Ajax)

Php 更正未授权访问和禁止访问的HTML状态代码。(使用Ajax),php,html,ajax,unauthorized,Php,Html,Ajax,Unauthorized,我的PHP+JS+Ajax应用程序要求用户登录,然后将登录数据保存到$\u会话 有三种类型的用户:用户、版主、管理员。每个人都比以前拥有更多的权利 所有查询都是对ajax_req.php进行的 因为我想保证ajax_req.php的安全,所以我检查$会话数据以确定用户是否登录以及他/她属于哪个组 其代码如下所示: if(isset($_SESSION['logged'])) { if(isset($_SESSION['group_id'])) { $group_id=(i

我的PHP+JS+Ajax应用程序要求用户登录,然后将登录数据保存到$\u会话

有三种类型的用户:用户、版主、管理员。每个人都比以前拥有更多的权利

所有查询都是对ajax_req.php进行的

因为我想保证ajax_req.php的安全,所以我检查$会话数据以确定用户是否登录以及他/她属于哪个组

其代码如下所示:

if(isset($_SESSION['logged'])) {
    if(isset($_SESSION['group_id'])) {
        $group_id=(int)$_SESSION['group_id'];

        if($group_id==ADMIN_GROUP) {
            $login_success=1;
        } else if ($group_id==MODERATOR_GROUP) {
            $login_success=1;
        } else if ($group_id==USER_GROUP) {
            $login_success=1;
        } else {
            $login_success=-1;
        }
    } else {
        $login_success=-1;
    }
} 

if($login_success<1) {
    header('HTTP/1.1 401 Unauthorized');
    $ret = array('status' => 'FALSE', 'txt' => 'Unauthorized access. Please check if You are still logged in.' );
    print json_encode($ret); 
    exit();
}
在我采取敏感行动之前

assert_right($_SESSION['group_id'], ADMIN_GROUP);
第二个问题:在第一种情况下返回401,在第二种情况下返回403是否正确?基本上,403的意思是“禁止”,根据它的意思是“请求是合法的,但服务器拒绝响应。与401未经授权的响应不同,身份验证不会有什么区别。”。我也检查了一下,这是关于另一个问题的

对我来说,403似乎是正确的,因为若用户已经登录,那个么他/她可能并没有管理员帐户。更重要的是,除非我犯了编程错误,或者用户对通过Ajax发送的数据进行了黑客攻击,否则用户永远不会看到这一点

还有一件事需要注意:401或403状态代码并没有显示给用户:Ajax和JavaScript使用它们来显示适当的错误消息。如果收到401,JavaScript将显示文本:“您似乎未登录到服务器。请打开新窗口并登录以继续。登录后,单击此处检查连接。”。如果收到403,则显示文本:“您似乎没有足够的权限来完成此操作。”


我是否正确使用了这些错误代码?

您的返回代码一点都不重要,因为这是AJAX请求,所以您可以返回任何您想要的内容。返回错误代码,然后使用JS进行处理,然后将消息返回给用户。示例用户单击按钮delete,他/她可能没有执行此操作的权限,因此返回json:status:error,type:permission。然后向用户显示属于此错误类型的消息

你应该把1和2结合在一起。编写一个函数或类来检查它们的命令。例如:

$check = $session_check(USER_COMMAND);
if ($check) //has right
else //no right.

function session_check($command){
     $userCmdList = array(COMMAND_1,2,3,4);
     $modCmdList = array(COMMAND_2,3,4,5,6,7);
     switch ($_SESSION['group_id']){
          case "admin":
               return true;
               break;
          case "mod":
               if !in_array($command,$modCmdList) return false;
               else return true;
               break;
          case "user":
               if !in_array($command,$userCmdList) return false;
               else return true;
               break;
          default:
               break;
    }
}
还记得为每个会话使用唯一的哈希,以防止会话hjhack


p/S:这是一个简单的答案,遵循您当前的工作流程。其他改进的方法总是可用。

对于每个会话使用唯一的哈希是什么意思?我在登录后使用PHP会话启动(没有“记住我”选项)。当调用SESSION_start()时,PHP会创建SESSION_ID本身。我假设浏览器在关闭浏览器后删除会话cookie。如果我错了,请纠正我。(还有一个“注销”按钮,它使用会话销毁并取消设置会话cookie。)您可以组合客户端代理+客户端IP+客户端会话id。$\u会话['hash']=md5($agent.$IP.session\u id());这对于每个浏览器和用户都是唯一的。若你们在等待会话破坏,那个么若黑客在用户注销之前拿走了用户的会话呢?通过使用会话散列,如果黑客使用此会话散列id,但会话散列无效,则此会话将被销毁。(登录用户的会话将存储在数据库中)这是一项很好的技术。客户端代理和IP可能会随着时间的推移而变化,但我认为它们至少在浏览器打开时是相同的:)我会考虑使用这个。
$check = $session_check(USER_COMMAND);
if ($check) //has right
else //no right.

function session_check($command){
     $userCmdList = array(COMMAND_1,2,3,4);
     $modCmdList = array(COMMAND_2,3,4,5,6,7);
     switch ($_SESSION['group_id']){
          case "admin":
               return true;
               break;
          case "mod":
               if !in_array($command,$modCmdList) return false;
               else return true;
               break;
          case "user":
               if !in_array($command,$userCmdList) return false;
               else return true;
               break;
          default:
               break;
    }
}