Home  >  Article  >  PHP Framework  >  How to use the Hyperf framework for permission control

How to use the Hyperf framework for permission control

WBOY
WBOYOriginal
2023-10-20 13:46:58912browse

How to use the Hyperf framework for permission control

How to use the Hyperf framework for permission control

Introduction:
When developing an application, it is often necessary to implement permission control functions and give users different roles different permissions. The Hyperf framework is a high-performance PHP microservices framework that provides many powerful features and extensions, including flexible permission control. In this article, we will explore how to use the Hyperf framework to implement permission control and provide specific code examples.

1. Create a permission table
First, we need to create a permission table to store various permission information. Database tables can be created through Hyperf's data migration function. Execute the following command in the terminal to generate the migration file:

php bin/hyperf.php gen:migration create_permissions_table

Then add the following content to the generated migration file:

<?php

use HyperfDatabaseSchemaSchema;
use HyperfDatabaseSchemaBlueprint;
use HyperfDatabaseMigrationsMigration;
use HyperfDbConnectionDb;

class CreatetPermissionsTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        $tableName = 'permissions';
        $exists = Db::table('information_schema.TABLES')
            ->where('TABLE_SCHEMA', config('databases.default.dbname'))
            ->where('TABLE_NAME', $tableName)
            ->first();

        if (!$exists) {
            Schema::create($tableName, function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name')->unique()->comment('权限名称');
                $table->string('guard_name')->default('web')->comment('守卫名称');
                $table->timestamps();
            });
        }
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('permissions');
    }
}

Next, we need to add the following content to the main configuration file of the project Add the following content to config/autoload/permissions.php:

<?php

return [
    'default' => [
        'guard_name' => 'web',
        'permissions' => [
            // 在这里添加你的权限
            'create_post',
            'edit_post',
            'delete_post',
            // ...
        ],
    ],
];

Then run the following command on the command line to perform database migration:

php bin/hyperf.php migrate

2. Define the user role model
In the Hyperf framework, we need to define a user model, which is used to manage user roles and permissions. We can create a user model by inheriting the HyperfDatabaseModelModel class. Execute the following command in the terminal to generate the user model:

php bin/hyperf.php gen:model User

Then add the following code to the generated user model file:

namespace AppModel;

use HyperfDbConnectionModelModel;
use HyperfUtilsApplicationContext;

class User extends Model
{
    protected $guarded = [];

    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }

    public function hasPermission($permission)
    {
        foreach ($this->roles as $role) {
            if ($role->hasPermission($permission)) {
                return true;
            }
        }
        return false;
    }

    public function givePermission($permission)
    {
        $permissionModel = Permission::where('name', $permission)->first();
        if (!$permissionModel) {
            throw new Exception("Permission {$permission} does not exist.");
        }
        $this->permissions()->sync($permissionModel, false);
    }

    public function revokePermission($permission)
    {
        $permissionModel = Permission::where('name', $permission)->first();
        if (!$permissionModel) {
            throw new Exception("Permission {$permission} does not exist.");
        }
        $this->permissions()->detach($permissionModel);
    }

    public function permissions()
    {
        return $this->belongsToMany(Permission::class, 'user_permissions');
    }
}

3. Define the role model
In the Hyperf framework, We also need to define a role model, which is used to manage roles and permissions. Likewise, we can create a role model by inheriting the HyperfDatabaseModelModel class. Execute the following command in the terminal to generate the role model:

php bin/hyperf.php gen:model Role

Then add the following code to the generated role model file:

namespace AppModel;

use HyperfDbConnectionModelModel;

class Role extends Model
{
    protected $guarded = [];

    public function users()
    {
        return $this->belongsToMany(User::class);
    }

    public function permissions()
    {
        return $this->belongsToMany(Permission::class);
    }

    public function hasPermission($permission)
    {
        return $this->permissions->contains('name', $permission);
    }

    public function givePermission($permission)
    {
        $permissionModel = Permission::where('name', $permission)->first();
        if (!$permissionModel) {
            throw new Exception("Permission {$permission} does not exist.");
        }
        $this->permissions()->sync($permissionModel, false);
    }

    public function revokePermission($permission)
    {
        $permissionModel = Permission::where('name', $permission)->first();
        if (!$permissionModel) {
            throw new Exception("Permission {$permission} does not exist.");
        }
        $this->permissions()->detach($permissionModel);
    }
}

4. Define the permission model
In the Hyperf framework, We also need to define a permission model, which is used to manage permission information. Likewise, we can create a permission model by inheriting the HyperfDatabaseModelModel class. Execute the following command in the terminal to generate the permission model:

php bin/hyperf.php gen:model Permission

Then add the following code to the generated permission model file:

namespace AppModel;

use HyperfDbConnectionModelModel;

class Permission extends Model
{
    protected $guarded = [];

    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}

5. Define permission middleware
Next, we You need to create a permission middleware to check whether the user has sufficient permissions to access a route. Execute the following command in the terminal to generate middleware:

php bin/hyperf.php gen:middleware PermissionMiddleware

Then add the following code to the generated middleware file:

namespace AppMiddleware;

use HyperfHttpMessageStreamSwooleStream;
use HyperfHttpServerContractRequestInterface;
use HyperfUtilsContext;
use PsrContainerContainerInterface;
use PsrHttpMessageResponseInterface;
use PsrHttpServerMiddlewareInterface;
use PsrHttpServerRequestHandlerInterface;

class PermissionMiddleware implements MiddlewareInterface
{
    protected $container;

    protected $request;

    public function __construct(ContainerInterface $container, RequestInterface $request)
    {
        $this->container = $container;
        $this->request = $request;
    }

    public function process($request, RequestHandlerInterface $handler): ResponseInterface
    {
        $user = $this->request->getAttribute('user');
        $permissions = $this->request->route->permission;

        if ($user && $user->hasPermission($permissions)) {
            return $handler->handle($request);
        }

        return $this->response(403, 'Forbidden');
    }

    protected function response($code, $message)
    {
        $data = [
            'code' => $code,
            'message' => $message,
        ];

        return Context::get(ResponseInterface::class)->withBody(new SwooleStream(json_encode($data)));
    }
}

6. Use permission middleware
In the routing definition , we can set the corresponding permission middleware for the route by using ->middleware('permission:xxx'). Execute the following command in the terminal to generate a routing file:

php bin/hyperf.php gen:controller PermissionController

Then add the following code to the generated routing file:

namespace AppController;

use AppMiddlewarePermissionMiddleware;
use HyperfHttpServerAnnotationController;
use HyperfHttpServerAnnotationMiddleware;
use HyperfHttpServerAnnotationRequestMapping;

/**
 * @Controller
 * @Middleware(PermissionMiddleware::class)
 */
class PermissionController
{
    /**
     * @RequestMapping(path="/permission", methods="get")
     * @Middleware("permission:create_post")
     */
    public function createPost()
    {
        // 处理创建文章的逻辑
    }

    /**
     * @RequestMapping(path="/permission", methods="get")
     * @Middleware("permission:edit_post")
     */
    public function editPost()
    {
        // 处理编辑文章的逻辑
    }

    /**
     * @RequestMapping(path="/permission", methods="get")
     * @Middleware("permission:delete_post")
     */
    public function deletePost()
    {
        // 处理删除文章的逻辑
    }
}

7. Usage examples
Where permission control is required , we can check whether the user has sufficient permissions through the following methods:

$user = User::find(1);

if ($user->hasPermission('edit_post')) {
    // 给用户权限来编辑文章
} else {
    // 权限不足
}

8. Summary
This article introduces the detailed steps of how to use the Hyperf framework for permission control, and provides specific code examples. By using the permission management functions provided by the Hyperf framework, we can easily implement flexible permission control functions for our applications. I hope this article is helpful to you, thank you for reading!

The above is the detailed content of How to use the Hyperf framework for permission control. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn