React 中的简单授权

大多数真实世界应用程序需要身份验证和授权,而身份验证将某个实体识别为有效的用户,授权则根据其角色和权限定义用户可以执行的操作。

我们通常不需要任何特殊的模块或库来处理授权,在大多数情况下,几个实用程序功能就足够了.您在应用程序中提供的身份验证或授权解决方案可能会有所不同:您可以决定在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);

我正在使用逻辑&&运算器进行短路评估,因此,只有当hasRoleisAllowed函数返回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 以获取本文中所见的基本示例。

保持冷静

Published At
Categories with 技术
Tagged with
comments powered by Disqus