Maison >cadre php >Laravel >Conseils sur la fonction d'autorisation de Laravel : Comment implémenter l'héritage des autorisations et la gestion des relations d'héritage

Conseils sur la fonction d'autorisation de Laravel : Comment implémenter l'héritage des autorisations et la gestion des relations d'héritage

PHPz
PHPzoriginal
2023-11-04 09:28:49863parcourir

Conseils sur la fonction dautorisation de Laravel : Comment implémenter lhéritage des autorisations et la gestion des relations dhéritage

Laravel est un framework doté de fonctionnalités riches pour développer rapidement des applications Web. Sa fonctionnalité d’autorisations en fait partie. Dans cet article, nous commencerons à apprendre deux problèmes clés du système d'autorisations de Laravel : l'héritage des autorisations et la gestion des relations d'héritage, et nous mettrons en œuvre une démonstration de code fonctionnel.

Héritage des autorisations

L'héritage des autorisations fait référence au passage des autorisations d'un rôle à un autre. Dans certains cas, il est nécessaire d'attribuer des autorisations à un rôle, puis de transmettre ces autorisations à un rôle plus spécifique. Par exemple, si nous souhaitons gérer les autorisations d'une organisation, nous pouvons accorder à l'administrateur de l'unité toutes les autorisations de l'organisation. Plutôt que d'avoir à attribuer des autorisations à chaque employé.

Laravel fournit la fonction "Permission Inheritance", que nous pouvons utiliser pour transmettre les autorisations d'un rôle à un autre. Commençons par apprendre à implémenter cette fonctionnalité.

Avant de commencer, nous devons créer une base de données. Nous allons créer deux tables : rôles et autorisations.

CREATE TABLE `roles` (
  `id` int(10) UNSIGNED NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `parent_id` int(10) UNSIGNED DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `permissions` (
  `id` int(10) UNSIGNED NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Nous allons créer une table de rôles pour stocker les rôles, y compris les champs id, name et parent_id. Le champ id est une clé primaire et doit être unique. Le champ Nom stockera le nom du rôle. Le champ parent_id est facultatif et représente le rôle parent de ce rôle. Nous allons également créer le tableau des autorisations, qui comprend les champs d'identifiant et de nom. Le champ id est une clé primaire et doit être unique. Le champ de nom stockera le nom de l'autorisation.

Voici des exemples de données de la table des rôles :

INSERT INTO `roles` (`id`, `name`, `parent_id`) VALUES
(1, 'Admin', NULL),
(2, 'Manager', 1),
(3, 'User', 2);

Dans les exemples de données ci-dessus, nous avons créé trois rôles. Le premier rôle est appelé "Administrateur", qui n'a pas de rôle parent ; le deuxième rôle est appelé "Manager". son rôle parent est « Administrateur » ; le troisième rôle est appelé « Utilisateur » et son rôle parent est « Gestionnaire ».

Maintenant, nous devons implémenter la fonction d'héritage des autorisations. Pour ce faire, nous devons créer une fonction qui recevra un ID de rôle, trouvera tous les rôles parents de ce rôle et renverra les autorisations pour ces rôles. Nous allons également implémenter une autre fonction qui recevra un ID de rôle et un nom d'autorisation et vérifiera si le rôle dispose de cette autorisation, soit en l'accordant directement, soit en en héritant.

Voici la fonction pour obtenir tous les rôles parents d'un rôle :

public function getPermissionsByRoleId($roleId) {
    $permissions = [];
    $role = Role::find($roleId);
    while($role) {
        $parent = Role::find($role->parent_id);
        if($parent) {
            $permissions = array_merge($permissions, $parent->permissions);
        }
        $role = $parent;
    }
    return $permissions;
}

Le code ci-dessus crée un tableau $permissions et parcourt les rôles parents du rôle en commençant par le rôle spécifié. Lorsque le rôle parent est trouvé, ajoutez toutes ses autorisations au tableau $permissions. Si le rôle parent n'est pas trouvé, la boucle while se termine et le tableau $permissions est renvoyé.

Nous allons maintenant implémenter une autre fonction qui recevra l'ID du rôle et le nom de l'autorisation et vérifiera si le rôle dispose de cette autorisation. Voici le code de la fonction :

public function hasRolePermission($roleId, $permissionName) {
    $permissions = $this->getPermissionsByRoleId($roleId);
    foreach($permissions as $permission) {
        if($permission->name == $permissionName) {
            return true;
        }
    }
    return false;
}

Le code ci-dessus appelle la fonction getPermissionsByRoleId pour obtenir toutes les autorisations pour le rôle et l'itère pour trouver l'autorisation spécifiée. Si l'autorisation est trouvée, la fonction renvoie vrai. Sinon, il renvoie faux.

Maintenant que nous avons appris comment implémenter l'héritage des autorisations, concentrons-nous sur l'apprentissage de la façon dont Laravel implémente la gestion des relations d'héritage.

Gestion des relations successorales

Dans certains cas, il est nécessaire de créer des relations successorales et de les utiliser dans l'application. Par exemple, si nous avons une application de gestion de département, chaque département peut avoir un responsable. La relation entre le manager et le service peut s'établir par voie d'héritage.

Dans Laravel, nous pouvons utiliser la fonction « association polymorphe » pour établir des relations d'héritage. Commençons par apprendre à le mettre en œuvre.

Nous allons créer un tableau de données des départements. La table des départements représentera les départements de l'application et comprend les champs id, name et parent_id. Le champ id est une clé primaire et doit être unique. Le nom du champ Nom stockera le nom du département. Le champ parent_id est facultatif et représente le service parent de ce service. De plus, nous allons créer une table d'utilisateurs. Ce tableau contient des informations de base sur un utilisateur, y compris les champs ID et Nom. Nous devons également créer une table des utilisateurs. La table contiendra les champs user_id, userable_id et userable_type. Parmi eux, le champ user_id est une clé étrangère pointant vers le champ id dans la table users. Les champs userable_id et userable_type sont des champs polymorphes qui représentent le modèle auquel l'utilisateur est associé.

Voici la structure de la table de données requise et les exemples de données :

CREATE TABLE `departments` (
  `id` int(10) UNSIGNED NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `parent_id` int(10) UNSIGNED DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `users` (
  `id` int(10) UNSIGNED NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `userables` (
  `id` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `userable_id` int(10) UNSIGNED NOT NULL,
  `userable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `departments` (`id`, `name`, `parent_id`) VALUES
(1, 'Administration', NULL),
(2, 'Finance', 1),
(3, 'Sales', 1),
(4, 'IT', 1),
(5, 'Accounts Payable', 2),
(6, 'Accounts Receivable', 2),
(7, 'Engineering', 4),
(8, 'Development', 7),
(9, 'Testing', 7);

INSERT INTO `users` (`id`, `name`) VALUES
(1, 'User One'),
(2, 'User Two'),
(3, 'User Three');

INSERT INTO `userables` (`id`, `user_id`, `userable_id`, `userable_type`) VALUES
(1, 1, 1, 'Department'),
(2, 1, 2, 'Department'),
(3, 2, 3, 'Department'),
(4, 3, 9, 'Department');

Dans les exemples de données ci-dessus, nous avons créé un département nommé « Administration », qui n'a pas de département parent nommé « Finance », « Ventes », « Informatique » ; Les départements « Administration » ont pour département parent le département « Administration ». De plus, les départements nommés « Comptes fournisseurs » et « Comptes clients » ont le département « Finances » comme service parent. Un département nommé « Ingénierie » a le département « Informatique » comme département parent. Les départements « Développement » et « Tests » ont pour département parent le département « Ingénierie ».

Nous utiliserons ces données de département et d'utilisateur pour établir des relations d'héritage.

Voici l'association polymorphe entre la table des utilisateurs et les départements :

class Userable extends Model {
    public function userable() {
        return $this->morphTo();
    }

    public function user() {
        return $this->belongsTo(User::class);
    }
}

以上代码定义了 userable 函数。该函数返回与 userable 模型相关联的模型。在我们的情况下,userable 将返回 Department 模型或任何其他相关模型。

接下来,我们定义 Department 模型:

class Department extends Model {
    public function users() {
        return $this->morphMany(Userable::class, 'userable');
    }

    public function parent() {
        return $this->belongsTo(Department::class, 'parent_id');
    }

    public function children() {
        return $this->hasMany(Department::class, 'parent_id');
    }
}

以上代码定义了三个函数。users 函数返回将 Userable id 与当前模型实例相关联的所有 User 实例。parent 函数返回这个部门的一个父级部门。children 函数返回所有直接关联的部门。

现在,我们可以使用这些函数来获取一个部门的所有直接用户。以下是 getAllUsers 函数。

public function getAllUsers() {
    $users = [];
    foreach($this->users as $user) {
        $users[] = $user->user;
    }
    return $users;
}

此函数将从当前部门中检索所有用户,并返回一个数组,其中包含这些用户。

最后,我们将定义 User 模型:

class User extends Model {
    public function userables() {
        return $this->hasMany(Userable::class);
    }

    public function departments() {
        return $this->morphToMany(Department::class, 'userable');
    }

    public function getDepartmentAttribute() {
        $department = null;
        foreach($this->userables as $userable) {
            if($userable->userable_type == 'Department') {
                $department = $userable->userable;
                break;
            }
        }
        return $department;
    }
}

以上代码定义了三个函数。userables 函数返回该用户的所有可关联实例。departments 函数返回与此用户相关联的所有部门。getDepartmentAttribute 函数将从 userables 中找到所有 Department 实例,并返回它们中的第一个。

以上所有代码示例可以一起使用,以计划实现 Laravel 权限系统的两个主要问题:权限继承和继承关系管理。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn