React中的简单授权
大多数现实世界的应用程序都需要身份验证和授权。 虽然身份验证将某些实体标识为有效用户,但授权根据他/她的角色和权限定义允许用户执行的操作。
我们通常不需要任何特殊的模块或库来处理授权,并且在大多数情况下,一些实用程序函数就足够了。 您为应用程序中的身份验证或授权提供的解决方案可能会有所不同:您可能决定将用户状态管理保留在 Redux 上,您可能决定构建一个专用模块等。
让我们看看如何在 React 中处理简单的基于角色的授权。
请记住,以下内容用于客户端授权,可以轻松绕过。 客户端的授权更多地与用户体验有关,而不是与安全性有关。 您需要确保角色在后端受到保护。
简单授权
假设我们有一个 user
对象,通常通过在认证后调用类似 /me
的端点获得,具有以下结构:
const user = { name: 'Jackator', // ... roles: ['user'], rights: ['can_view_articles'] };
一个用户有多个 权限,可以分组为 角色。 对于你的应用,你可能只需要角色,或者只需要权限,或者两者都需要,没关系。 REST API 可能会为您提供嵌套在角色中的权限,这也无关紧要,请记住这一点以使解决方案适应您的需求。 重要的是我们有一个用户。
然后,我们可以创建一个 auth.js 文件,其中包含一些我们可以用来检查用户授权的实用功能:
auth.js
export const isAuthenticated = user => !!user; export const isAllowed = (user, rights) => rights.some(right => user.rights.includes(right)); export const hasRole = (user, roles) => roles.some(role => user.roles.includes(role));
通过使用 Array 原型中的 some
和 includes
方法,我们正在检查该用户是否至少具有指定的权限或角色之一。 这应该足以执行一些基本的权限检查。
由于 user
可以保存在任何地方,例如在 Redux 中,我们允许将其作为参数传递给函数。
最后让我们创建一个基本的 React 组件,它使用 auth.js 中定义的函数来有条件地显示不同的 UI:
应用程序.js
import React from 'react'; import { render } from "react-dom"; import { hasRole, isAllowed } from './auth'; const user = { roles: ['user'], rights: ['can_view_articles'] }; const admin = { roles: ['user', 'admin'], rights: ['can_view_articles', 'can_view_users'] }; const App = ({ user }) => ( <div> {hasRole(user, ['user']) && <p>Is User</p>} {hasRole(user, ['admin']) && <p>Is Admin</p>} {isAllowed(user, ['can_view_articles']) && <p>Can view Articles</p>} {isAllowed(user, ['can_view_users']) && <p>Can view Users</p>} </div> ); render( <App user={user} />, document.getElementById('root') );
我正在使用逻辑 &&
运算符进行短路评估。 这样,只有当 hasRole
或 isAllowed
函数返回 true
时,才会渲染以下内容。
尝试将用户更改为管理员,您会看到显示了与管理员相关的 UI。
条件路由
使用此解决方案,如果您使用 React Router,您可以使用相同的方法有条件地渲染路由:
import React from 'react'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; const App = ({ user }) => ( <BrowserRouter> <Switch> {hasRole(user, ['user']) && <Route path='/user' component={User} />} {hasRole(user, ['admin']) && <Route path='/admin' component={Admin} />} <Route exact path='/' component={Home} /> </Switch> </BrowserRouter> );
React Router 使用 Route
组件可以很容易地声明和组合路由,我们可以利用它:只有当 <Route>
组件被渲染时,路由才会被路由器添加和处理通过 hasRole
评估。
包起来
您已经了解了如何自己进行简单的授权形式。 根据应用程序和要求,解决方案可能会有所不同,但核心概念应该是相同的。
您可以在 这个 Codesandbox 中查看本文中看到的基本示例。
保持冷静🦄