React:如何根据用户角色安全地显示组件

3
我正在尝试在reactMeteor中仅当当前用户是管理员时显示管理仪表板。
我调用一个服务器方法来检查用户权限,并只在该方法返回true时呈现管理员组件。
由于此服务器调用是异步的,因此组件不会呈现。通常我使用状态来管理这个异步调用,但我不想在这里暴露任何状态(不希望有人更改状态并访问管理员仪表板)。
以下是代码:
export default class AdminChecker extends Component {
  isItAdmin() {
    // Get the id of current user
    const userId = Meteor.userId();
    if (userId) {
      // call a server method which returns true if current user is Admin
      Meteor.call('checkAdminId', userId, (err, authorized) => {
        if (err) {
          console.log(err);
          return null;
        }
        return (authorized) ? <AdminDashboard /> : null;
      });
    }
  }
  render() {
    return (
      <div className="admin-temp-container">
        {this.isItAdmin()}
      </div>
    );
  }
}

我认为可以将这个逻辑放在父组件中,并将isItAdmin的结果作为prop发送到adminDashboard(只有当props为true时,adminDashboard组件才会显示信息)。

但我不确定这是否安全。是否可以使用Chrome React开发者工具或类似工具更改props?

非常感谢。


1
是的,在控制台中可以轻松更改prop。您的方法并不特别安全,但可能足以满足您的需求。 - px1mp
1
在客户端组件中,依赖于指示管理员角色的布尔标志非常困难。你需要为每个东西都有一个方法对应项,因为你需要假设有人会在客户端上伪造管理员角色。 - Jankapunkt
1
我不知道这是否能帮到你,但通常在我的项目中,我使用redux store来获取用户的角色,并编写一个高阶组件从redux store读取状态并渲染正确的组件。当然,redux devtools必须仅在开发模式下启用。 - zied hajsalah
1
忘记提到非常敏感的区域也可以在服务器端呈现,只有当角色匹配时才能发布仅供管理员使用的数据。 - Jankapunkt
1
我不得不强调,你绝对不能在客户端上存储任何敏感信息。完全不要相信客户端。在你的情况下,唯一安全的解决方案是 SSR。其他所有解决方案都会存在漏洞。 - Styx
显示剩余2条评论
1个回答

6
我认为这个问题有两个方面(评论也暗示了这一点):
首先,您不应该期望能够在客户端执行安全控制。您必须在服务器上实现访问控制逻辑(即,执行管理员操作的任何API都必须检查执行操作的用户是否是管理员)。
一旦您完成了这个步骤(也许您已经完成了),那么您可能需要使用props或state来存储用户是否为管理员(就像您会在应用程序中存储任何其他数据一样)。
关键是,一旦您在服务器上强制执行了安全性,那么如果用户操纵状态以进入管理员仪表板,那么并不重要:服务器将不允许用户查看任何真实数据或执行任何操作。
这与服务器端渲染完全无关。只要用于获取管理员数据和执行管理员操作的API实现了自己的访问控制检查,您就可以构建一个安全的管理员仪表板。

我完全同意你的观点,但问题本身并不是关于实现服务器端检查或类似内容的。问题是“基于用户角色,在客户端上显示/隐藏UI组件是否安全”。对于这个问题,我的答案是“永远不要相信客户端”。对于这个特定的问题,唯一安全的解决方案是SSR。 - Styx
我想,当获取数据以填充管理仪表板时,可以将SSR用作访问控制的解决方法。但是,如果要调用API执行操作呢?我想你不能使用AJAX...你需要使用HTML表单或其他东西。 - John Girata
即使您已经实现了客户端访问控制,您仍然面临一个问题,即允许任意用户执行管理员操作的服务。这将使您暴露于各种漏洞之中。例如,您需要阻止对服务的Internet访问(以防有人发现API)。但即使如此,在您的环境中任何地方出现任意代码执行漏洞都将授予对这些管理员功能的访问权限。 - John Girata
漏洞清单还有很多,但这些注释太短了,无法全部列出... - John Girata
我之前提到了SSR,是为了隐藏输入控件或任何可能指示潜在攻击向量的元素。当然,这只是一个适当且安全的API设计的补充。但你总结得很好。 - Jankapunkt
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接