首页
Preview

使用Laravel APIs和React前端实现细粒度权限控制

本文将讲解如何使用 Laravel APIs 作为后端和 React.js 作为前端(分离的应用程序)实现细粒度权限系统。

由于前端与后端分离并通过 APIs 连接,我们将不会使用 Laravel blade 视图作为常规方式。

介绍

在许多 Web 应用程序中,我们都有一个角色和权限系统。每个用户都有一个角色,每个角色都有自己的权限,然后每个权限用于授权我们应用程序中的特定功能,如下图所示:

图片来源:sukanyasen.medium.com

那么,什么是细粒度权限 🤔?

通常,细粒度权限是指系统授予你的特权,允许你根据某些要求构建特定于网站的角色。- 来源

通过细粒度权限,你可以在同一视图中根据用户被授予的权限有不同的内容。

例如,

我们有一个应用程序有两个用户:

图片来源:sukanyasen.medium.com

如上图所示,

  • 具有管理员角色的用户拥有完全访问权限(所有权限)…因此,他可以访问、创建、更新、删除或评论帖子以及用户和其他部分。
  • 具有编辑角色的用户只拥有有限的访问权限(有限权限)…他只能访问帖子视图并编辑它们。

因此,细粒度权限背后的想法是,我们可以根据系统设置的权限控制我们的视图,并根据用户授予的权限在视图中显示/隐藏特定功能。

后端

我们将在我创建的现有 Laravel 应用程序(后端 API)上工作,通过使用 Laravel Sanctum 实现身份验证。

此 API(Laravel 应用程序)仅包含两个模型:

  • User 模型。
  • Post 模型。

它们的控制器、资源、迁移、种子和路由都已准备好。

没有太复杂的东西!只有一个后端 API 来获取、创建、更新和删除帖子,以及使用 API 令牌进行身份验证。

现在,让我们写一些代码!

现在是时候动手写一些代码了🖐

在 Laravel 中,使用 @spatie/laravel-permissions 包实现这样的系统非常容易,它可以帮助我们以非常简单的方式轻松管理用户角色和权限。

让我们先在我们的应用程序中安装 laravel-permissions 包(你可以遵循官方文档):

composer require spatie/laravel-permission

然后我们需要发布(配置、迁移):

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"

然后运行迁移:

php artisan migrate

现在,我们需要创建应用程序所需的所有权限,然后创建角色并为它们分配权限。然后将角色分配给特定用户,

让我们创建一个种子文件来执行此操作,运行以下命令:

php artisan make:seeder PermissionsSeeder

将创建一个种子类在 database/seeders/PermissionsSeeder.php,打开它并在 run 方法中编写种子代码。

你可以按照下面的代码:

解释上面的种子类:

  • 首先,如果需要,重置缓存的角色和权限。
  • 创建一个数组,其中包含我们应用程序中所有所需的权限,然后将它们存储在数据库中。
  • 创建 2 个角色(管理员具有完全权限,编辑者仅具有两个或有限权限)。
  • 最后一件事,将角色分配给用户。将 用户 1 分配为管理员和 用户 2 分配为编辑器。

然后,我们需要在 database/seeders/DatabaseSeeder.phprun 方法中调用 PermissionsSeeder.php 类,如下所示:

$this->call([
    PermissionsSeeder::class,
]);

然后运行播种命令:

php artisan db:seed

现在我们有了我们的用户和他们的角色和权限设置 🤓 🎉

  • 用户 1 作为管理员拥有所有权限
  • 用户 2 作为编辑器只拥有 2 个权限。

剩下两个步骤,完成后端!

  • 步骤 1 - 使用我们的应用程序 API 对给定资源授权用户操作(因为我们永远不信任客户端)。
  • 步骤 2 - 身份验证时返回用户的权限,以便稍后在我们的前端中使用。## 步骤1

使用 Laravel,你可以通过两种主要方式(使用 Gates,Policies)对给定资源授权用户操作。请查看 官方文档

在我的情况下,你需要根据你的情况来选择,我将使用 通过用户模型使用 Policies 授权 用户操作。

示例:

在我的 PostController.php 中,用户必须进行身份验证(登录)并被授权(具有访问帖子的权限)

以及其他控制器方法的授权。

步骤2

我有一个GET端点,它是(/auth/profile),用于通过请求中发送的访问令牌获取已认证用户的数据,然后响应用户的数据... 这很好,但我需要获取用户的角色权限与返回的用户数据。

我正在使用 Laravel 资源 来转换响应数据,因此我创建了一个名为 UserResource.php 的用户资源。 然后在我的 AuthController.phpprofile 方法中,我使用此资源返回已认证用户的数据,如下所示:

return response()->json([      ‘user’ => new UserResource(auth()->user())], 200);

我的当前 UserResponse.php

正如我之前所说,我需要添加用户的角色和用户的权限,因为我们将需要它们在前端。

因此,它将如下所示:

这就是后端的全部内容。 🤓 ✅

前端

首先,让我解释在我们的视图中使用权限以根据授予用户的权限显示/隐藏特定功能的常见方法。

常见方法是使用Laravel Blade Views..使用 Blade 指令(can、cannot、role、hasrole…等)非常容易。

例如:

但是在我们的情况下,我们使用 React.js 作为与 Laravel 分离的应用程序,通过 API 连接。因此,我们没有 Laravel Blade 指令进行授权!

这就是为什么在后端部分(步骤2)中,我们返回已认证用户和他的角色的所有权限。

让我解释

在我的 React 应用程序中,当用户使用 (/auth/sign-in) API 端点登录时,我使用 Cookies 存储登录令牌,而不是存储用户数据...因此,我需要在页面加载时获取已登录用户的数据,然后将其存储在状态管理(Redux、Context API 等)中。

那么如何获取已登录用户的数据?

使用 API 端点(/auth/profile)。

通过向 (/auth/profile) 发送带有 Cookies 中存储的 令牌 的 GET 请求,我们会得到以下响应:

我们将用户数据存储在我们的状态管理中(在我的情况下是 Context API),因此我们随后可以在应用程序的任何地方访问用户数据。

最后一步,我们可以实现自己的(can、cannot、hasrole…等)方法,以便我们可以使用它们授权特定功能,方式与 Laravel Blade 指令相同。

实现(can)方法的示例:

将此方法放置在获取用户数据的同一位置(在我的情况下是我的状态管理的 Auth 上下文),因为它需要用户数据(权限)进行检查。

然后我们只需在应用程序的任何地方导入(can)方法并将其用于以下方式:

这就是全部内容,我们完成了!

你可以使用 Vue.js/Angular.js/Svelte.js 等实现相同的方法,它不仅仅适用于 React.js。这只是使用 API 与与 Laravel 分离的前端应用程序的示例。

高级

此后,你可以构建一个控制并(创建/更新/删除)角色及其权限并轻松将角色分配给用户的仪表板,如下所示:

在仪表板中更新角色

通过创建一个端点来获取按部分(产品、帖子...)分组的角色权限,然后在更新时使用同步将权限同步到角色中,如下所示:

$role->syncPermissions($request->permissions);

等等。

GitHub - munafio/laravel-granular-permissions: The Backend API using Laravel for the tutorial…

后端源代码

别忘了查看我的GitHub账户,并在Twitter上关注我😁❤️

译自:https://blog.munafio.com/granular-permissions-with-laravel-apis-react-frontend-f5697441bb5

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
anko
宽以待人处事,严于律己修身。

评论(0)

添加评论