0

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

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

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

$_Session['loggedin'] - 登录时设置为 true 的布尔值

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

到目前为止,在每个页面上,我都会检查 login 是否设置为 true,并且我在每个页面上都进行了硬编码:

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

不过,我对这个解决方案不是很满意,因为我正在努力使其尽可能自动化——新客户将继续添加,人们应该可以在不费吹灰之力的情况下添加客户(所有这些都有效在这一点上很好,除了这个)

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

有处理这样的事情的好习惯吗?我想实现一些可以在所有用户之间使用的东西,并且每次添加新客户端时都不需要有人进入代码并更改客户端名称字符串。

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

4

2 回答 2

0

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

您还说您在每个客户端目录中有一个 index.php 文件。

并且您将文件夹与客户端一起放置在根目录下。我假设路径是:

/root/path/to/files/$$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");
}
于 2013-07-27T03:16:31.683 回答
0

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

如果您的文档根目录是/some/folder/public_html客户端数据/some/folder/data/Client/...,PHP 将发布特定文件夹的内容。您还可以将项目及其数据库密钥存储为文件夹。那么就不需要Client/Year/Project/but的目录结构了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]

索引.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 来保护实体的访问。此外,请求处理将在路由器->解析器->控制器链中构建。这只是这个想法的摘录。

于 2013-07-26T16:01:12.840 回答