Home  >  Article  >  PHP Framework  >  Advanced implementation of Laravel permission function: how to achieve multi-tenant permission isolation

Advanced implementation of Laravel permission function: how to achieve multi-tenant permission isolation

WBOY
WBOYOriginal
2023-11-02 16:35:181290browse

Advanced implementation of Laravel permission function: how to achieve multi-tenant permission isolation

Advanced implementation of Laravel permission function: How to implement multi-tenant permission isolation, specific code examples are needed

With the rapid development of the Internet, enterprises have demands for online applications more and more. In these applications, multi-tenant systems have become a common architectural pattern. Multi-tenant systems allow multiple tenants (enterprises, institutions, or individuals) to share an application, but their data and operations are isolated from each other.

When using the Laravel framework to develop a multi-tenant system, permission isolation is a very important issue. This article will introduce how to implement permission isolation in a multi-tenant system through Laravel's permission function, and give specific code examples.

First, we need to define the concept of multiple tenants, which can be represented by a tenant model. In Laravel, we can use Eloquent models to achieve this. Here is a simple tenant model example:

<?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;

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

    // 租户和用户之间的关联关系
    public function users()
    {
        return $this->hasMany(User::class);
    }
}

Next, we need to create an independent database for each tenant and configure multiple database connections in Laravel. We can define these database connections in the configuration file config/database.php as follows:

<?php

return [

    // 默认数据库连接
    'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [

        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

        'tenant' => [
            'driver' => 'mysql',
            'host' => env('TENANT_DB_HOST', '127.0.0.1'),
            'port' => env('TENANT_DB_PORT', '3306'),
            'database' => env('TENANT_DB_DATABASE', 'forge'),
            'username' => env('TENANT_DB_USERNAME', 'forge'),
            'password' => env('TENANT_DB_PASSWORD', ''),
            'unix_socket' => env('TENANT_DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

    ],

    // ...
];

In the above configuration file, we added a database connection named tenant and in the .env file Configure the corresponding connection information as follows:

TENANT_DB_HOST=127.0.0.1
TENANT_DB_PORT=3306
TENANT_DB_DATABASE=tenant_db
TENANT_DB_USERNAME=root
TENANT_DB_PASSWORD=secret

Next, we need to define a middleware in Laravel to implement multi-tenant permission isolation. We can use middleware to intercept requests and determine whether the requested tenant matches the tenant to which the currently logged-in user belongs, thereby achieving permission isolation. The following is a simple middleware example:

<?php

namespace AppHttpMiddleware;

use Closure;
use IlluminateSupportFacadesAuth;
use IlluminateSupportFacadesDB;

class TenantMiddleware
{
    public function handle($request, Closure $next)
    {
        $tenantId = $request->route('tenantId');
        $user = Auth::user();

        if ($user && $tenantId != $user->tenant_id) {
            abort(403, 'Access denied.');
        }

        $this->switchConnection($tenantId);

        return $next($request);
    }

    private function switchConnection($tenantId)
    {
        // 切换到对应租户的数据库连接
        config(['database.connections.tenant.database' => "tenant_{$tenantId}"]);

        DB::purge('tenant');
    }
}

In the above example, we first obtain the information of the currently logged in user through the Auth::user() method, and determine whether the tenant to which the user belongs matches the requested tenant. ; If there is no match, a 403 error is returned. Then, we switch to the database connection of the corresponding tenant through the switchConnection() method.

Finally, we need to register the middleware in the routing file and add the corresponding routing example:

<?php

use IlluminateSupportFacadesRoute;

// ...

Route::group(['middleware' => ['auth', 'tenant']], function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::get('/reports', [ReportsController::class, 'index']);
});

In the above example, we registered two middleware: auth is used to authenticate users Login status, tenant is used for multi-tenant permission isolation. We can obtain the information of the currently logged in user by calling the Auth::user() method and make a judgment in the middleware.

The above are the basic ideas and code examples for implementing multi-tenant permission isolation. Of course, actual application scenarios may be more complex and require corresponding adjustments and expansions based on actual needs. But in any case, we can use Laravel's powerful permission functions and middleware mechanism to achieve permission isolation in multi-tenant systems to ensure the independence and security of data between different tenants.

The above is the detailed content of Advanced implementation of Laravel permission function: how to achieve multi-tenant permission isolation. 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