大多数真实世界应用程序需要身份验证和授权,而身份验证将某个实体识别为有效的用户,授权则根据其角色和权限定义用户可以执行的操作。
我们通常不需要任何特殊的模块或库来处理授权,在大多数情况下,几个实用程序功能就足够了.您在应用程序中提供的身份验证或授权解决方案可能会有所不同:您可以决定在Redux上保持用户状态管理,您可以决定构建专用模块等。
让我们看看如何在 React 中处理简单的基于角色的授权。
<$>[警告] 请记住,下列内容适用于客户端授权,可以轻松绕过。
简单许可
假设我们有一个用户
对象,通常通过在身份验证后调用一个像/me
这样的终端点来获得,其结构如下:
1const user = {
2 name: 'Jackator',
3 // ...
4 roles: ['user'],
5 rights: ['can_view_articles']
6};
一个用户有几个权利,可以分为角色。对于你的应用程序,你可能只需要角色,或者只需要权利,或者两者都不重要。REST API可能会给你角色中的权利,也不重要,只需记住这一点,以便将解决方案适应你的需求。
然后,我们可以创建一个 auth.js 文件,其中包含一些实用功能,我们可以使用它们来检查用户授权:
1[label auth.js]
2export const isAuthenticated = user => !!user;
3
4export const isAllowed = (user, rights) =>
5 rights.some(right => user.rights.includes(right));
6
7export const hasRole = (user, roles) =>
8 roles.some(role => user.roles.includes(role));
通过从 Array 原型中使用某些
和包括
方法,我们正在检查该用户是否至少具有指定的权限或角色之一。
由于用户
可以在任何地方保留,例如在Redux中,我们允许将其作为参数传递给函数。
最后,让我们创建一个使用 auth.js 定义的函数的基本 React 组件,以条件显示不同的 UI:
1[label App.js]
2import React from 'react';
3import { render } from "react-dom";
4import { hasRole, isAllowed } from './auth';
5
6const user = {
7 roles: ['user'],
8 rights: ['can_view_articles']
9};
10
11const admin = {
12 roles: ['user', 'admin'],
13 rights: ['can_view_articles', 'can_view_users']
14};
15
16const App = ({ user }) => (
17 <div>
18 {hasRole(user, ['user']) && <p>Is User</p>}
19 {hasRole(user, ['admin']) && <p>Is Admin</p>}
20 {isAllowed(user, ['can_view_articles']) && <p>Can view Articles</p>}
21 {isAllowed(user, ['can_view_users']) && <p>Can view Users</p>}
22 </div>
23);
24
25render(
26 <App user={user} />,
27 document.getElementById('root')
28);
我正在使用逻辑&&
运算器进行短路评估,因此,只有当hasRole
或isAllowed
函数返回true
时,将返回以下内容。
尝试将用户更改为管理员,你会看到与管理员相关的用户界面显示。
条件路线
借助此解决方案,如果您使用的是 React Router,则可以使用相同的方法有条件地渲染路线:
1import React from 'react';
2import { BrowserRouter, Switch, Route } from 'react-router-dom';
3
4const App = ({ user }) => (
5 <BrowserRouter>
6 <Switch>
7 {hasRole(user, ['user']) && <Route path='/user' component={User} />}
8 {hasRole(user, ['admin']) && <Route path='/admin' component={Admin} />}
9 <Route exact path='/' component={Home} />
10 </Switch>
11 </BrowserRouter>
12);
React Router 可以轻松地使用Route
组件来声明和构成路线,我们可以利用它:路线只有通过通过hasRole
评估来渲染<Route>
组件时,路由器才会添加和处理路线。
包装上
您已经看到如何自己做一个简单的授权形式。 解决方案可能对您来说略有不同,取决于应用程序和要求,但核心概念应该是一样的。
您可以查看 此 Codesandbox 以获取本文中所见的基本示例。
保持冷静