仅允许特定用户查看页面

时间:2013-07-26 15:15:29

标签: php security session authorization

所以我正在构建一个允许客户端查看我们为他们创建的工作的身份验证系统。每个客户只有一个帐户。我正在试图找出一种方法来检查每个页面是否允许登录的人查看所述内容。

基本上文件结构如下:Client / Year / Project /然后在项目文件夹中有特定类别的文件夹(flash,登录页面等)。在每个文件夹中都有一个index.php文件,用于处理显示目录或项目。我需要检查每个索引页面是否有权登录的用户查看该页面。

目前,我有几个会话变量:

$ _ Session ['loggedin'] - 只是登录时设置为true的bool

$ _ Session ['client'] - 这个值在登录时从数据库中获取。它只是一个客户全名的字符串(它也用于显示目的)。

截至目前,在每个页面上,我都会检查是否将loggedin设置为true,并在每个页面上对此进行了硬编码:

if(!isset($_SESSION['loggedin']) || $_SESSION['client'] != 'Clientname'){
   unset($_SESSION);
   session_destroy();
   header("Location: http://www.homepage.com");
}

我对这个解决方案不是很满意,因为我试图让它尽可能自动化 - 新的客户端将继续被添加,人们应该可以添加客户端而不会有太大的麻烦(全部在这一点上工作得很好,除了这个)

我必须检查以确保客户端是正确的,因为以下情况可能会发生:客户端A登录并且登录会话设置为true ...但是,如果他们导航到客户端B的文件夹结构,它只检查是否有人登录,他们将能够访问它。

处理这样的事情是否有良好的做法?我想实现可以在所有用户中使用的东西,并且不需要有人在每次添加新客户端时都进入代码并更改客户端名称字符串。

任何形式的逻辑帮助都会很棒!

2 个答案:

答案 0 :(得分:0)

您可以将客户端数据存储在公共可见目录结构之外的目录中,并使用mod_rewrite(如果您使用的是Apache)将所有请求重定向到将启动FrontController的单个index.php。该控制器根据请求字符串和会话cookie初始化认证和授权过程。

如果您的文档根目录是/some/folder/public_html,则客户端数据将存储在/some/folder/data/Client/...中,PHP将发布特定文件夹的内容。您还可以将项目及其数据库密钥存储为文件夹。然后,您不需要Client/Year/Project/some/folder/data/{project_key}/...的目录结构。使用此解决方案,目录导航更简单。

这里有一些简短的摘录:

的.htaccess

使用mod_rewrite

重定向请求
RewriteEngine On
RewriteBase /path/to/client/data
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?request=$1 [QSA, L]

的index.php

此脚本将初始化数据库连接,控制器和会话并处理请求。

// initialization of database connection    
$connection = ...

// controller initialziation
$controller = new FrontController($connection, ...);

// you could encapsulate the session in its own class to make
// easy requests to the session.
$session = new Session(...);

// select the requested resource by its path
$resource = $controller->selectResourceByPath($_GET['request']);

// resouce was not found
if (!$resource) {
    $controller->showNotFound($_GET['request']);
    exit(0);
}

// validate if the session is started. If not, redirect to the login page.
if (!$session->isStarted()) {
  $controller->redirect('login');
  exit(0);
}

$user = $session->getUser();

// user is not logged in
if (!$user) {
   $controller->redirect('login');
   exit(0);
}

// this is a very simple solution. You could build up separate
// authentication/authorization layer.
if ($resource->hasAccess($user))
  $controller->showResource($resource);
else
  $controller->showAccessDenied($user, $resource);

通常,您将使用路由器和防火墙类以及ACL来保护实体的访问权限。此外,请求处理将在路由器 - >解析器 - >控制器链中构建。这只是这个想法的摘录。

答案 1 :(得分:0)

您似乎已经拥有了一个身份验证系统,因为您正在设置$ current_client = $ _SESSION ['client']。

另外,您说每个客户端目录中都有一个index.php文件。

你在根目录下设置了客户端文件夹。我假设路径是:

/根/路径/到/文件/ $$ CLIENT $$ / ....

您需要做的就是将当前路径/ / client与$ current_client进行比较。

// returns true if $str begins with $sub
function beginsWith( $str, $sub ) {
    return ( substr( $str, 0, strlen( $sub ) ) == $sub );
}

$authorized = beginsWith(__FILE__, '/root/path/to/files/' . $current_client) ;

将其添加到您的授权中,而不是硬编码客户端名称。

if(!isset($_SESSION['loggedin']) || !$authorized){
   unset($_SESSION);
   session_destroy();
   header("Location: http://www.homepage.com");
}
相关问题