Reactjs 如果用户可以更改状态,如何在React中实现访问控制
我正在尝试用react-redux实现一个基于角色的访问控制系统。到目前为止,我一直在阅读,并看到了一些大致的方法:Reactjs 如果用户可以更改状态,如何在React中实现访问控制,reactjs,redux,Reactjs,Redux,我正在尝试用react-redux实现一个基于角色的访问控制系统。到目前为止,我一直在阅读,并看到了一些大致的方法: <View> {!user && <LoginScreen />} {user && <WelcomeScreen user={user} />} </View> {!用户&} {用户&&} 它基本上是使用变量或状态来测试条件并授予对某些组件的访问权。当我看到这篇文章时,我陷入了
<View>
{!user && <LoginScreen />}
{user && <WelcomeScreen user={user} />}
</View>
{!用户&}
{用户&&}
它基本上是使用变量或状态来测试条件并授予对某些组件的访问权。当我看到这篇文章时,我陷入了困境:
如果用户可以篡改状态并查看他们没有权限的组件,那么什么是确保基于角色访问的正确方法?将用户数据存储为客户机中的position:employee
可以更改为position:manager
,这样,即使没有提出休息请求,他们也可以看到经理可以使用哪些选项
我目前正在使用会话cookie来验证用户服务器端,任何对数据敏感的REST get/POST都是经过身份验证的——但这如何转换到客户端
用户登录
->服务器验证
->服务器发回保存user.position的会话变量或发送json(user)
->客户端从服务器或json(用户)查看会话,将user.position存储在state.user.position中
->state.user.position在条件if中用于确定是否如上所述显示组件
---*但是*-->client进入并更改state.user.position并以任何方式访问组件
如果我们可以更改客户端中的状态,那么如何在react/redux中安全地使用条件测试 这样的事情是由后端处理的,而不是由React处理的。无论你做什么,都不要只需抓取所有数据并将其过滤到React中即可。我不知道如何根据您的示例区分用户,但是,为了简单起见,我假设您正在使用。在这个实现中,登录时会生成一个令牌,您可以将其安全地存储在本地存储或redux中。对于您进行的所有api调用,您应该为它们附加一个令牌。然后,对于登录用户的每次呼叫,后端应执行以下几项操作:
- 验证令牌签名
- 从令牌获取用户id并获取权限/角色
- 检查用户是否有权访问api调用
{'userid':5,'position':manager}
。
因此,如果我是一个优秀的攻击者,我只需将manager更改为admin,看看它能从哪里得到我,但如果我不好,我会尝试所有从0到10000的用户ID,以manager和admin作为位置,看看它们能从哪里得到我。
然后尝试使用随机用户id,比如时间戳的散列。不过,攻击面只是略有增加。现在你对这些黑客很生气。好吧,我要加密这个会话变量,但我不能将密钥存储在React中,因为这是可以破解的,我只需将加密的东西附加到每个请求上,解密、验证并批准它是否有效。在这一点上,您基本上几乎重新发明了JWT。永远不要相信客户!如果员工将其角色更改为经理,您的客户将尝试通过API调用获取与经理相关的数据,然后API将检查授权并拒绝。(正如您所说的REST api所做的)这也意味着您不必事先加载敏感数据并“隐藏”它。我曾考虑使用JWTs来实现这一点,但也有一些人反对,其中一位是:。我有一个存储用户信息的会话变量,例如
position:manager
。我想另一种解释整个问题的方法是,如何安全地获取会话信息并使用它来显示组件,而不需要客户端对其进行操作。一旦我检索到会话数据并将其用于测试用例,它就会成为一个安全问题,因为用户可以更改输入以更改显示。例如,如果有人登录并让服务器对其进行身份验证,并随用户信息的响应提供会话变量-我可以将user.position
存储在状态中,理论上,以后可以使用它来确定是否基于该条件显示组件。问题是,如果我们使用条件显示,用户可以操纵该状态并以任何方式获得对组件的访问权。我已经通过更新答案解决了这个问题。这就是问题所在——除了某种令牌,你不能在状态中存储太多。JWT包含用户信息,即使没有密钥也很容易解密,但除非试图欺骗的人能够访问你的秘密,否则无法验证。博客中提到的一些问题很容易解决。这不是一个防弹系统,但如果问题是我如何安全地知道哪个用户是什么角色,这就是答案。好吧,让我们假设有一个jwt和user.position
inside-如果你做了类似解码(jwt)的事情并掌握了它,在对组件进行条件测试之前,您仍然会将其存储在某个变量或状态中。在这一点上,它是如果{some_variable__,客户机可以改变===true?show():deny()}
,正如我所说,这并不重要。导航项目仅限tak