logo

Đang load dữ liệu

logo devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER

Đào tạo - Phần mềm - Cho thuê nhân sự

  • 0969.609.003
  • 0978.611.889
  • Trang chủ
  • Các khoá đào tạo
    • Chuyên đề WEB - PHP

      • Lập trình web với HTML5 - CSS3- JQuery - Bootstrap - Ajax - [36 giờ]
      • Lập trình web frontend - reactjs - [75 giờ]
      • Lập trình web với mã nguồn mở PHP&MYSQL - PHP FRAMEWORK [126 giờ]

      Chuyên đề Mobile

      • Lập trình Games/Apps trên nền tảng Android - [120 giờ]
      • Lập trình Games/Apps trên nền tảng IOS - [120 giờ]

      Chuyên đề JAVA

      • Ngôn ngữ lập trình hướng đối tượng với java - [40 giờ]
      • Lập trình ứng dụng với java - [100 giờ]
      • Lập trình web site với java framework (JPA, HIBERNATE, SPRING MVC, SPRINGBOOT) - [276 giờ]

      Chuyên đề NETWORK/SECURITY

      • Khoá học Quản trị hạ tầng mạng CCNA v6 - [72 giờ]
      • Khoá học quản trị hệ thống với Windows SERVER 2012- [72 giờ]
      • Chuyên gia bảo mật hệ thống CompTIA + - [110 giờ]

      Chuyên đề .NET

      • Nền tảng lập trình hướng đối tượng với C# - [40 giờ]
      • Lập trình ứng dụng WINDOWS FORM - [100 giờ]
      • Lập trình Web với ASP.NET MVC 5, WebAPI - [145 giờ]

      Chuyên đề khác

      • Ngôn ngũ lập trình C/C++ - [80 giờ]
  • Lập trình cho trẻ em
  • Dịch vụ
    • Đào tạo theo như cầu
    • Cung cấp thiết bị - Phần mềm
    • Tư vấn - Thiết kế mạng hạ tầng
    • Tư vấn - Triển khai dịch vụ mạng
    • Tư vấn - Tư vấn, triển khai giám sát hệ thống
    • Thực tập dự án
  • Lịch khai giảng
  • Tin tức
    • Tin tức và sự kiện
    • Tin hoạt động
    • Tin công nghệ
    • Hội thảo, workshop, Codecam
    • Thông tin việc làm
    • Cẩm nang chia sẻ kiến thức
  • Tiện ích
  • Liên hệ

Tin công nghệ

Mar - 2019

28

Multi-Tenancy là gì? How to implement with Simple Trait in Laravel?

Tin công nghệ

Người viết: Phan Thanh

Multi-Tenancy là gì?

Multi-Tenancy is a single instance of software that serves multiple customers privately.

Hiểu đơn giản Multi-Tenancy là một hệ thống web application có nhiều khách hàng cùng sử dụng nhưng dữ liệu giữa các khách hàng hoàn tập độc lập, khách hàng này không thể truy cập vào dữ liệu của khách hàng kia.

Có thể kể đến vài ví dụ như:

  • Hệ thống quản lý khách sạn cho phép nhiều khách sạn có thể truy cập với những tài khoản độc lập, dữ liệu độc lập, nhưng vẫn cùng chung 1 hệ thống site.
  • Hệ thống quản lý công văn sử dụng trong tổng công ty và nhiều công ty con, cùng site nhưng dữ liệu độc lập.
  • Hệ thống quản lý dự án Jira
  • Hệ thống CRM của zoho, saleforce ….

Bài toán multi-tenancy thực tế gặp rất nhiều và tùy theo từng hệ thống sẽ triển khai theo mỗi cách khác nhau. Ở bài viết này, mình sẽ cùng bạn tìm hiểu để implement một cách đơn giản nhất vào project Laravel Framework nhé (Vì mình cũng đang tìm hiểu chưa có biết nhiều)

Bài toán

Có một hệ thống quản lí khách sạn và danh sách book phòng theo từng khách sạn.

  • CEO của khách sạn A đăng kí tài khoản vào hệ thống, sau đó tạo các khách sạn để quản lí.
  • CEO của khách sạn B cũng tương tự vậy (đăng kí tài khoản vào hệ thống, sau đó tạo các khách sạn để quản lí.)

Vấn đề:

  • Nếu không Multi-Tenancy: CEO A có thể thấy được các thông tin của khách sạn ông B gồm: tên, địa chỉ của các khách hàng đã đặt phòng trên khách sạn ông B ==> Lộ thông tin rồi, ông A lúc này có thể lợi dụng những thông tin có được để thực hiện những hành vi không đúng: spam email + số điện thoại chẳng hạn…
  • Nếu có Multi-Tenancy: Tất cả dữ liệu khách sạn của ông A và ông B hoàn toàn độc lập, không liên quan và không ai có thể thấy hay truy cập vào các dữ liệu của người khác (trừ thằng admin).

Migration

Tạo thêm 1 trường created_by_user_id trong bảng hotels. Trường này dùng để xác định ông nào đã tạo ra cái khách sạn ấy trên hệ thống.

1
2
3
4
5
6
 
Schema::table('hotels', function (Blueprint $table) {
    $table->unsignedBigInteger('created_by_user_id');
    $table->foreign('created_by_user_id')->references('id')->on('users');
});
 

 

  • Note: Từ ver 5.8, Laravel đã thay đổi kiểu dữ liệu (data type) trường Id là big int. Vậy nên khi liên kết khóa ngoại, bạn cũng phải set data type của trường liên kết là big int nhé.

Sau đó, thêm created_by_user_id vào fillable trong Model

1
2
3
4
5
6
7
8
9
10
 
protected $fillable = [
    'title',
    'name',
    'address',
    'created_at',
    'updated_at',
    'created_by_user_id',
];
 

Bây giờ làm sao để field tự insert vào DB khi user tạo mới một Hotels? Bạn có thể sử dụng Model Observers. Tuy nhiên để mở rộng và tái sử dụng ở các Model khác nhau, mình sẽ tạo ra 1 Trait Multitenantable thay vì cứ mỗi Model mình lại tạo ra 1 Observers như vầy.

Trait Multitenantable

Tạo file app/Traits/Multitenantable.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
namespace App\Traits;
 
trait Multitenantable {
 
    protected static function bootMultitenantable()
    {
        if (auth()->check()) {
            static::creating(function ($model) {
                $model->created_by_user_id = auth()->id();
            });
        }
    }
 
}
 

 

  • Note: hàm bootMultitenantable() với name convention là bootXYZ(), Laravel sẽ tự chạy hàm này khi Trait được sử dụng (Có thể gọi nó là trait “constructor”)

Trait Multitenantable sẽ có nhiệm vụ khi user đó tạo một thứ gì đó thì nó tự động insert vào DB ở field created_by_user_id với value là id của user đang đang nhập.

Implement trait này vào model Hotel

1
2
3
4
5
6
7
8
9
10
11
 
use App\Traits\Multitenantable;
 
// ...
 
class Hotel extends Model
{
    use Multitenantable;
    // ...
}
 

Kết quả khi tạo mới 1 Hotel:

Có thể bạn quan tâm

Java đang giãy chết?

Học lập trình thế nào để không thất nghiệp?

Filtering Data By User

Đây là bước quan trọng nhất để giải quyết bài toán: Tất cả dữ liệu khách sạn của ông A và ông B hoàn toàn độc lập, không liên quan và không ai có thể thấy hay truy cập vào các dữ liệu của người khác.

Trong Laravel rất đơn giản, ta dùng Global Scope để fillter tất cả các query trên Model.

Thêm vào trait Multitenantable như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
namespace App\Traits;
 
use Illuminate\Database\Eloquent\Builder;
 
trait Multitenantable {
 
    protected static function bootMultitenantable()
    {
        if (auth()->check()) {
            static::creating(function ($model) {
                $model->created_by_user_id = auth()->id();
            });
 
            static::addGlobalScope('created_by_user_id', function (Builder $builder) {
                $builder->where('created_by_user_id', auth()->id());
            });
        }
    }
 
}
 

Oki, lúc này nó sẽ lọc tất cả các khách sạn của user đang nhập hiện tại, còn các khách sạn của user khác hoàn toàn ko hiển thị và không access vào được.

SQL thuần nó sẽ như này:SELECT * FROM hotels WHERE created_by_user_id=1 (với 1 là id của user đang đăng nhập).

Kết quả ở Hotel list:

Thử truy cập vào thằng hotel có id=1 mà chưa set trường created_by_user_id: 

404 ngay

Bây giờ bạn thử set created_by_user_id=2, back lại và xem kết quả nhé (Thêm 1 record ở list + có thể access vào rồi)

What About Administrator To See All Entries?

Ngoài ra để đảm bảo thằng Admin có thể view được hết các dữ liệu trên hệ thống thì bạn check thêm if nhé.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
protected static function bootMultitenantable()
{
    if (auth()->check()) {
        static::creating(function ($model) {
            $model->created_by_user_id = auth()->id();
        });
 
        // if user is not administrator - role_id 1
        if (auth()->user()->role_id != 1) {
            static::addGlobalScope('created_by_user_id', function (Builder $builder) {
                $builder->where('created_by_user_id', auth()->id());
            });
        }
    }
}
 

Ok, vậy là coi như mình đã implement Multi-Tenancy trên model Hotels rồi.

Giờ muốn tái sử dụng Trait này, thì bạn cứ use trong Model là ngon ngay (Nhớ model implement phải có trường created_by_user_id)

Kết luận

Trên đây mình đã giới thiệu với bạn Multi-Tenancy là gì? Cách implement Multi-Tenancy một cách đơn giản nhất vào project Laravel Framework như thế nào. Hi vọng từ bài viết này bạn có thể hiểu về Multi-Tenancy và áp dụng vào các bài toán của mình.

Nguồn: Sưu tầm từ internet via Viblo

Các bài viết cùng chủ đề

Việt Nam khả năng thiếu 150.000 đến 200.000 nhân sự IT mỗi năm
Việt Nam khả năng thiếu 150.000 đến 200.000 nhân s...
Tổng quan ngành khoa học máy tính
Tổng quan ngành khoa học máy tính
8 xu thế công nghệ đáng chú ý nhất trong năm 2021
8 xu thế công nghệ đáng chú ý nhất trong năm 2021...
Tìm hiểu về API? Tại sao API lại được trọng dụng!
Tìm hiểu về API? Tại sao API lại được trọng dụng!...
Học ngôn ngữ lập trình nào để bắt kịp xu thế công nghệ năm 2021
Học ngôn ngữ lập trình nào để bắt kịp xu thế công ...
Nên làm việc ở công ty Product hay công ty Outsourcing?
Nên làm việc ở công ty Product hay công ty Outsour...

Các khóa đào tạo chuyên đề

Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Lập trình ứng dụng trên nền tảng android Lập trình ứng dụng trên nền tảng android
Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack

Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
Lập trình ứng dụng với WINDOWS FORM Lập trình ứng dụng với WINDOWS FORM
Lập trình ứng dụng với JAVA (FORM) Lập trình ứng dụng với JAVA (FORM)
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
Lập trình frontend với reacjs (Full) Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

DEVMASTER ACADEMY

Địa chỉ: Tầng 6 - Tòa nhà VIỆN CÔNG NGHỆ
Số 25, Vũ Ngọc Phan - Láng Hạ - Đống Đa - Hà Nội

Hotline: 0969 609 003 | 0978 611 889

devmaster.contact@gmail.com

hna.tvchung@gmail.com

CÁC KHÓA HỌC CHUYÊN ĐỀ

  • Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
  • Lập trình ứng dụng trên nền tảng android
  • Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
  • Lập trình ứng dụng với WINDOWS FORM
  • Lập trình ứng dụng với JAVA (FORM)
  • Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
  • Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
  • Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER - Học thực tế * Làm thực tế * Cam kết việc làm
Copyright by Ⓒ DEVMASTER 2015