html - SQL 查询内联表,打印到 HTML <select> 标签

标签 html mysql sql sql-server coldfusion

我的任务是更新一个旧应用程序并遇到了麻烦。该应用程序在 Railo(ColdFusion) 上运行,带有 MySQL 5 数据库。

该应用程序使用基于角色的身份验证来管理用户。之前的开发者似乎没有修改/添加/删除用户的代码,只是直接修改了数据库列。我已经处理了添加/删除用户部分,没问题。修改部分是我绊倒的地方。

下面是角色和成员的基本表格布局。

MEMBERS TABLE
id | username | role
 1 | user1    | Administrator,User,Group1,Group2
 2 | user2    | User,Developer
 3 | user3    | SuperUser,Group1,Group2
 4 | user4    | SuperUser,Developer
 5 | user5    | Guest

ROLES TABLE
role_id | role_name
      1 | Administrator
      2 | Developer
      3 | SuperUser
      4 | Guest
      5 | User
      6 | Group1
      7 | Group2

要修改用户的角色,我的第一个想法是使用一个简单的 HTML 选择标记和几个 CFQUERY。类似于下面的代码。

<select name="role" multiple="multiple" size="7">
<cfoutput>
<option value="#GetRole.role_name#" <cfif GetRole.role_name = GetUser.role>checked</cfif>>#GetRole.role_name#</option>
</cfoutput>
</select>
<CFQUERY NAME="GetRole" DATASOURCE="#request.dataSource#">
  SELECT role_name
  FROM roles
</CFQUERY>

<CFQUERY NAME="GetUser" DATASOURCE="#request.dataSource#">
  SELECT a.id, a.username, a.role, b.role_name
  FROM members a
  LEFT JOIN roles b ON b.role_name = a.role
  WHERE a.id = #FORM.id#
</CFQUERY>

select 标签将从 GetRole 中提取并填充所有可用角色。 GetUser 查询将从成员表的列表中找到用户所属的当前角色。然后我会简单地在 select 标签中使用“checked”标志。那就是我碰壁的地方。无论我走哪条路,我都会不断遇到数组来列出问题。

当我添加一个新用户时,我只需使用"role = '#ListQualify(FORM.role,"")#' 并在我的选择标签中获取所有角色,添加一个逗号,并将它们吐到成员中。角色栏。

我什至尝试一步步创建一个数组:

<cfset roleArray = ArrayNew(1)>

<cfloop query = "GetUser">
<cfset temp = ArrayAppend(roleArray, "#role#")>
</cfloop>

<cfset roleList = ArrayToList(roleArray, ",")>

我也尝试执行 SQL FIND_IN_SET()。

无论我尝试什么,我都会得到可怕的 bool 错误数组。

建议?我应该尝试一种不同于 HTML 选择标签的方法吗?有什么我忽略的吗?任何帮助将不胜感激。

希望我把这个问题发好,这是我第二次在这里发问题。 :D

--------------------更新--------------------

我想补充一点,该应用程序在整个站点中使用 IsUserInRole() 来检查用户是否可以访问某些区域。例如:

 <cfif IsUserInRole("Administrator")>
 Do stuff here as an administrator.
 </cfif>

它也与多个组一起使用,ColdFusion 会自动查找以逗号分隔的每个组:

<cfif IsUserInRole("Administrator,Group1,Group2")>

ColdFusion 是否有更好的方式来管理角色?

--------------------更新#2--------------------

我发现最初的开发者使用 CFLOGIN 来为用户设置角色。我听说过关于 CFLOGIN 的恐怖故事,那么它是否应该被禁止以支持更好的东西?也许改为在 session 变量中设置用户角色?

<cfquery name="qryGetUserDetails" datasource="#request.datasource#">
SELECT *
FROM members
WHERE username = <cfqueryparam cfsqltype="cf_sql_varchar" value='#Trim(FORM.username)#'>
</cfquery>
<cflogin>
  <cfloginuser name="#FORM.username#" password="#FORM.password#" roles="#qryGetUserDetails.role#">
</cflogin>

注意到 cfquery 参数了吗? :D 我很快应用了从你们那里学到的东西! :D

最佳答案

适当角色系统的示例结构

我只是将这样的系统放入 Leigh 描述的应用程序中。不幸的是,虽然它是为 Railo 构建的,但它是基于 SQL Server 构建的,因此您可能需要修改 sql。

Users
UserID | Username ....

Roles
RoleID | RoleTitle ...

Permissions
UserID | RoleID

我的编辑用户查询如下所示

  • 你会注意到很长的 <cfqueryparam>标签。对于 Railo 和 ACF,它们都是抵御 sql 注入(inject)的关键防线。

  • 编辑:使用 Leigh 编写的更清晰的查询进行了更新。它比用于相同目的的我的版本更干净。

  • 我确实添加了第 6 行 ( and r.roleID in (select distinct pm.roleID from permissions pm where userID = <cfqueryparam cfsqltype="int" value="#session.userID#">) )。这确保了审核用户可以影响的唯一角色是他们自己所在的角色。

-

/* pull user details and role in one query */
SELECT  ur.*, CASE WHEN p.UserID IS NOT NULL THEN 1 ELSE 0 END AS HasRole
FROM   (SELECT u.*, r.RoleID, r.RoleTitle
        FROM   Users u CROSS JOIN Roles r
        WHERE  u.UserID = <cfqueryparam cfsqltype="int" value="#url.userID#">
and r.roleID in (select distinct pm.roleID from permissions pm where userID = <cfqueryparam cfsqltype="int" value="#session.userID#">)) ur
LEFT JOIN Permissions p
    ON p.RoleID = ur.RoleID
    AND p.UserID = ur.UserID;

/* get permissions separately */
SELECT r.RoleID, r.RoleTitle, CASE WHEN p.RoleID IS NOT NULL THEN 1 ELSE 0 END AS HasRole
FROM   Roles r LEFT JOIN Permissions p
        ON p.RoleID = r.RoleID
        AND p.UserID = <cfqueryparam cfsqltype="int" value="#url.userID#">

在表单本身中,我有这段代码。

<cfoutput query="GetUser" group="username">
...other form elements...
<input type="checkbox" name="roleschanged" value="1" onchange="if ($(this).prop('checked')) { $('.rolesCheck').removeAttr('disabled'); } else { $('.rolesCheck').attr('disabled','false'); }"> Editing Roles?<br><br>
<cfoutput group="roleID">
  <input type="checkbox" name="roleID" value="#roleID#" class="rolesCheck" disabled #(hasrole eq 1 ? "checked" : "")#> #RoleTitle#<br>
</cfoutput>
..
</cfoutput>

复选框加载已禁用,但如果用户是该角色的一部分,则会选中它们,如果不是,则取消选中。 roleschanged 复选框可以启用它们,因此可以更改角色,并且还在处理页面上起到关键作用,表示用户角色已被编辑。

在表单处理代码中,我有。

<cfif isDefined("form.rolesChanged") and form.rolesChanged eq 1><cfquery datasource="#request.dsn#">
  delete from Permissions
   where userID = <cfqueryparam cfsqltype="int" value="#val(url.userID)#">
     and roleID in (select distinct pm.roleID from permissions pm where userID = <cfqueryparam cfsqltype="int" value="#session.userID#">)
</cfquery>

<cfloop list="#form.roleID#" index="i">
  <cfquery datasource="#request.dsn#">
    insert into Permissions(userID,roleID)
     values(<cfqueryparam cfsqltype="int" value="#val(url.userID)#">,<cfqueryparam cfsqltype="int" value="#val(i)#">)
  </cfquery>
</cfloop></cfif>

Form.roleschanged 的​​最终目的是让这些查询不会在每次运行页面时运行,而不管角色是否采取行动。

虽然这是最终目的,但它确实允许审核用户跳过更改数据而无需重置表单的其余部分。

为了直观地表示该功能,这就是在页面加载时禁用复选框的原因。

我的角色表还有一个 Area 字段,它是他们可以编辑的区域的绝对路径,比如......

RoleID, RoleTitle, RoleArea
1       Pages      /wwwroot/cpanel/cms/
2       News       /wwwroot/cpanel/news/

每当用户尝试访问 cpanel 中的任何文件夹时,我都会进行检查,如果他们没有与他们尝试访问的文件夹相匹配的角色,他们就会被踢出注销。

我也可以(但不能)使用此表来构建管理链接,以便管理员只能看到指向他们可以使用的区域的链接。 (我从我的 cms 中提取链接,但我的 cms 条目也有指向角色表的链接。唯一的区别是更基本的路由将链接到 index.cfms 列出用户可以在每个文件夹中做什么,而我实际上使用的方法使用允许我提供直接链接..并不是一个显着的收获)。

关于html - SQL 查询内联表,打印到 HTML <select> 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26227103/

相关文章:

php - 包含数据库值和用户输入的表

html - 将鼠标悬停在文本上时出现 'fade in' 效果问题

php - 使用Bootstrap,php和ajax的数据表

mysql - 向MySql插入数据并在datagridview中显示

sql - 将合并替换为 case

mysql - 我想在 mysql workbench 表中同一列的同一字段中有 2 个不同的值?

html - 将标题限制为图像的宽度

javascript - 有没有办法将控制台日志从 JavaScript 打印到 HTML 中?

MySQL : can CASE - vary its query between Insert or Select?

mysql - MySQL表的重复记录