4

我是 PHP 和 MYSQL 的新手,试图创建一个用户可以用来将数据输入数据库的网站。我正在尝试做的一个例子是各种银行及其提供的各种服务的数据库。例如,花旗银行的用户在我的网站上创建了一个帐户,他将输入他的登录 ID、密码、电子邮件和名称他的银行(在这种情况下是花旗银行)。

成功创建帐户并登录后,他将成为花旗银行的“管理员”帐户,有权创建、删除、插入和查看仅来自花旗银行的所有数据。他还可以进一步创建和删除 Outlets,并为该 outlet 创建/删除 SubUser 帐户。SubUser 帐户将拥有 Admin 帐户将拥有的所有权限减去创建更多子用户的权利,但仅限于 Outlet它负责。管理员和子帐户都将通过该网站登录。

我列出了我认为帐户需要的权利:

Rights to database
SELECT,INSERT,UPDATE,DELETE,(JOIN?)

我目前正在考虑为管理员帐户实施下表:

Admin
+----------+-----------+------------+------------+
|  BankID  | BankName  |  UserName  |  Password  |
+----------+-----------+------------+------------+
|  1       | Citibank  |  CitiAdmin |  PassCiti  |
|  2       | StanChart |  StanAdmin |  PassStan  |
|  3       | HSBC      |  HSBCAdmin |  PassHSBC  |
+----------+-----------+------------+------------+

其中 BankID 的类型为 SERIAL,而 BankName、UserName 和 Password 将由用户在创建帐户时输入。我没有将上表拆分为 2 个表的原因,其中一个包含 BankID 和 BankName 以及其他包含用户名和密码的内容是为了便于使用,因为我觉得将其拆分是不必要的,并且会对其进行过度规范化。

虽然下表适用于子用户帐户:

SubUsers
+------+------------+--------------+-------------+
|  ID  |  OutletID  |  Name        |  Password   |
+------+------------+--------------+-------------+
|  1   |  1         |  CitiSub1    | PassSub1    |
|  2   |  1         |  CitiSub2    | PassSub2    |
|  3   |  2         |  StanSub1    | PassSub1    |
|  4   |  2         |  StanSub2    | PassSub2    |
|  5   |  3         |  HSBCSub1    | PassSub1    |
|  6   |  4         |  HSBCSub2    | PassSub2    |
+------+------------+--------------+-------------+

通过这样做,在用户登录时,我将从 $_POST[User] 和 $POST[Pass] 获取用户条目,并匹配从查询中提取的数据

$query="SELECT Username AND Password FROM Admin AND SubUsers";

如果匹配,用户将登录。通过这样做,我能够实现第一级验证,只有注册用户才能访问数据库。

但是,我将如何限制对管理员帐户和子用户帐户的访问。管理员帐户只能访问与他的银行有关的数据,而子用户帐户将只能访问与他的网点有关的数据。

我考虑过使用 PHP 会话通过更改登录查询从

$query="从管理员和子用户中选择用户名和密码";

到一个查询,首先从 Admin 中选择用户名和密码,并通过它运行 $_POST[User] 和 $_POST[Pass],如果没有匹配,它将从 SubUser 中提取用户名和密码并重复该过程,并且会根据匹配发生在 Admin 表还是 SubUser 表中,将结果记录到会话中。

然而,这样做只会改变用户在登录时可用的网页,而不是他们对数据库本身的实际访问。我能想到的使用这种方法的最接近的解决方案是为用户创建一组全新的网页,具体取决于无论用户是管理员还是子用户,我都不愿意这样做,因为我还是编程新手,并且增加网页数量只会增加不可避免地出现的错误数量。

是否有任何其他方法来限制用户访问数据库,或其他解决方案来优化我正在尝试做的事情?

我已经查看了如何为多个用户配置 phpMyAdmin - 每个用户都只能访问他们的数据库 ,但这对我来说有点过于技术性,并且似乎正在处理用户对数据库而不是表的访问。

任何建议/帮助/指导将不胜感激。

4

1 回答 1

0

多么有趣和透彻的问题。它是那种需要一本书才能彻底回答的类型。我很佩服你的野心。

首先设计合理。

  1. 问问自己用户可能需要执行哪些操作并为他们命名。将特权名称存储在表中后,您可以根据需要将它们分配给角色或用户。您可以在 PHP 级别验证执行每件事的能力,方法是在每个操作之前检查是否应用了适当的权限,或者通过将每个操作编写为包含权限验证的函数。

  2. 将银行 ID 和分行 ID 作为外键放在每个表中。这样,您只需将 bankid 和 branchid 作为“AND”添加到您的 WHERE 子句中。这样您只需要一个数据库,但您可以使用智能编写的 SQL 控制谁可以看到什么。

  3. 如果您需要用户能够对他们的数据运行 SQL,请确保所有查询都通过添加必要的 AND (bankid='%s' AND branchid='%s') 子句的函数运行。这有效地分离了数据。如果需要,您可以添加对返回数据的检查,还可以考虑使用加密(每家银行的不同密钥),尽管这有点远。

这几乎就是应用层控制的意思。PHP 应用程序根据存储的权限选择您有权访问的数据。考虑到有意义的名称和冗长的描述,我无法再次强调计划您的权限的重要性。当你开始时,它似乎有很多工作,但它会有所作为。它肯定比为每个用户创建一个新数据库要好。不用担心会填满您的 SERIAL id - BIGINT 每秒可以处理超过 200,000 年的一百万笔交易。

一旦设计完成,身份验证就是下一个障碍。我认为你应该在写任何花哨的东西之前这样做,因为它真的很难写好。

我会做的是:

收集银行、分行和用户名(允许这些在您的 HTML 中自动完成),然后输入密码。将密码存储为 SHA1 或 MD5 哈希。一旦通过身份验证,您将用户编号、银行和分行编号弹出到您的 $_SESSION 中,然后可以很容易地为 SQL 检索它们。为了增加安全性,尽管增加了复杂性,您也可以根据需要从数据库中选择这些数字。有些人建议将它们存储在单独的会话表中。

关于如何设计这类项目还有很多话要说,其中大部分内容都可以在本网站的其他地方找到,所以我不会再啰嗦了。请随时询问是否有任何不清楚的地方。

我希望这有帮助。

编辑:

处理特权。

没有简单的方法来处理特权。我为所有页面使用一个单独的头文件,自动提取特权信息:

一个。识别用户,通常从 $_SESSION 中选择用户号。湾。从数据库表 users_priveleges 中识别用户的权限。C。创建一个包含特权名称的数组。d。每当需要特权要求的操作时,For Each 通过数组进行比较。

此方法需要大量表格,并且可能对您的需要有点高级,但如果您有以下表格(此处仅提供骨架详细信息),它几乎可以无限扩展:

roles (role_id,rolename,role_detailed_description)
priveleges (privelege_id,privelegename,privelege_detailed_description)
users (user_id,user_details)
users_roles (user_id,role_id) (optional but a good idea)
users_priveleges (user_id,privelege_id) - priveleges granted to each user
roles_priveleges (role_id,privelege_id) - the priveleges each role has.

您所做的是在roles_priveleges 表中输入一行将角色链接到权限。对角色所需的所有权限重复此操作。可能很多。不是问题。

添加用户时,您授予他们一个角色。然后,我阅读了 roles_priveleges 表,并向超级用户提供了一个可能的角色列表作为复选框,如果通常会授予特权,则勾选,否则不勾选。超级用户根据需要从列表中取消选择或选择,然后保存列表。
保存列表时,我将 users_priveleges 表中该用户的所有条目标记为非活动状态,并为每个权限插入一个新行。这使您可以跟踪更改,重要的是,查看权限的日期,即使它们没有更改。它最终不会使用太多数据,因为 users_priveleges 中的每一行都包含三个 Bigint、一个布尔值和 2 个日期。

如果你不想授予一个用户一个他们的角色通常不会拥有的特权,那么你可以简单地使用roles_priveleges和users_roles。这最少需要较少的数据,但灵活性明显较低。

我承认我描述的方法有点不雅,但它提供了非常好的基于角色和基于用户的特权管理,同时将数据库保持在第 4 范式或更高。恕我直言,值得加倍努力,因为您的应用程序有一天会变得更大,现在添加这些东西比以后添加这些东西要容易得多。此外,从初学者的角度来看,创建虚拟数据并确保您的 SQL 连接正常工作,然后再开始一些更难的事情是非常容易的。

于 2013-05-28T09:41:12.470 回答