首頁  >  文章  >  php框架  >  如何使用Hyperf框架進行權限控制

如何使用Hyperf框架進行權限控制

WBOY
WBOY原創
2023-10-20 13:46:58903瀏覽

如何使用Hyperf框架進行權限控制

如何使用Hyperf框架進行權限控制

引言:
在開發一個應用程式時,往往需要實作權限控制功能,以不同的角色給予用戶不同的權限。 Hyperf框架是一個高效能的PHP微服務框架,提供了許多強大的功能和擴展,其中包括靈活的權限控制。在本文中,我們將探討如何使用Hyperf框架實現權限控制,並提供具體的程式碼範例。

一、建立權限表
首先,我們需要建立一個權限表,用於儲存各種權限資訊。可以透過Hyperf的資料遷移功能來建立資料庫表。在終端機中執行以下命令來產生遷移檔案:

php bin/hyperf.php gen:migration create_permissions_table

然後在產生的遷移檔案中加入以下內容:

<?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');
    }
}

接下來,我們需要在專案的主設定檔 config/autoload/permissions.php中加入以下內容:

<?php

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

然後在命令列中執行以下指令執行資料庫遷移:

php bin/hyperf.php migrate

二、定義使用者角色模型
在Hyperf框架中,我們需要定義一個使用者模型,該模型用於管理使用者的角色和權限。我們可以透過繼承HyperfDatabaseModelModel類別來建立一個使用者模型。在終端機中執行以下指令來產生使用者模型:

php bin/hyperf.php gen:model User

然後在產生的使用者模型檔中加入以下程式碼:

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');
    }
}

三、定義角色模型
在Hyperf框架中,我們也需要定義一個角色模型,用於管理角色和權限。同樣,我們可以透過繼承HyperfDatabaseModelModel類別來建立一個角色模型。在終端機中執行以下指令來產生角色模型:

php bin/hyperf.php gen:model Role

然後在產生的角色模型檔中加入以下程式碼:

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);
    }
}

四、定義權限模型
在Hyperf框架中,我們還需要定義一個權限模型,該模型用於管理權限資訊。同樣地,我們可以透過繼承HyperfDatabaseModelModel類別來建立一個權限模型。在終端機中執行以下指令來產生權限模型:

php bin/hyperf.php gen:model Permission

然後在產生的權限模型檔中加入以下程式碼:

namespace AppModel;

use HyperfDbConnectionModelModel;

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

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

五、定義權限中間件
接下來,我們需要建立一個權限中間件,用於檢查使用者是否有足夠的權限存取某個路由。在終端機中執行以下指令來產生中間件:

php bin/hyperf.php gen:middleware PermissionMiddleware

然後在產生的中間件檔案中加入以下程式碼:

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)));
    }
}

六、使用權限中間件
在路由定義中,我們可以透過使用->middleware('permission:xxx')來給路由設定對應的權限中間件。在終端機中執行以下指令來產生路由檔案:

php bin/hyperf.php gen:controller PermissionController

然後在產生的路由檔案中加入以下程式碼:

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()
    {
        // 处理删除文章的逻辑
    }
}

七、使用範例
在需要進行權限控制的地方,我們可以透過以下方式來檢查使用者是否擁有足夠的權限:

$user = User::find(1);

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

八、總結
本文介紹如何使用Hyperf框架進行權限控制的詳細步驟,並提供了具體的程式碼範例。透過使用Hyperf框架提供的權限管理功能,我們可以輕鬆地為我們的應用程式實現靈活的權限控制功能。希望本文對您有幫助,謝謝閱讀!

以上是如何使用Hyperf框架進行權限控制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn