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 原型中的 someincludes 方法,我们正在检查该用户是否至少具有指定的权限或角色之一。 这应该足以执行一些基本的权限检查。

由于 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')
);

我正在使用逻辑 && 运算符进行短路评估。 这样,只有当 hasRoleisAllowed 函数返回 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 中查看本文中看到的基本示例。

保持冷静🦄