Laravel manage invite system with Doorman

Doorman Trong số chúng ta, đã không ít lần phát triển các hệ thống sử dụng invite code để cho phép đăng kí mới hoặc sử dụng invite code để đăng kí một số trang web nào đó. Ví dụ như các trang download torrent private đều sử dụng invite code để hạn chế số lượng thành viên.

Chúng ta hoàn toàn có thể quản lý và phát trển hệ thống invite này bằng tay, tuy nhiên nó khá là rắc rối. Một cách dễ dàng hơn là sử dụng Doorman. Doorman cung cấp một cách để hạn chế quyền truy cập vào ứng dụng Laravel của bạn bằng cách sử dụng invite code và quản lý chúng:

Doorman có thể:

  • Có thể tạo invite code được gắn với một địa chỉ email cụ thể.
  • Có thể tạo invite có thể sử dụng cho bất cứ ai (dùng cho việc chia sẻ invite code).
  • Có thể giới hạn việc sử dụng invite code theo số lần cụ thể hoặc không giới hạn số lần sử dụng.
  • Có thể giới hạn việc sử dụng invite code trong một khoảng thời gian cụ thể hoặc không bao giờ hết hạn

Cài đặt

Chúng ta có thể cài đặt Doorman bằng composer:

$ composer require clarkeash/doorman

Tiếp theo, cập nhật providers trong config của Laravel:

// config/app.php
'providers' => [
    ...
    Clarkeash\Doorman\Providers\DoormanServiceProvider::class,
];

Và cập nhật facade:

// config/app.php
'aliases' => [
    ...
    'Doorman' => Clarkeash\Doorman\Facades\Doorman::class,
];

Cuối cùng, chạy migration:

$ php artisan migrate

Sau khi bạn chạy lệnh migrate, một bảng chứa invite code sẽ được tạo ra. Bạn có thể custom tên của bảng này bằng cách cập nhật config của Doorman sẽ được giới thiệu ở dưới.

Sử dụng

Tạo invite codes

Tạo một invite code sử dụng 1 lần và không có thời hạn sử dụng (không bao giờ hết hạn cho tới khi sử dụng)

Doorman::generate()->make();

Bạn có thể tạo nhiều code bằng câu lệnh dưới đây:

Doorman::generate()->times(5)->make();

Để tạo code sử dụng được nhiều lần chúng ta sử dụng ->uses(), dưới đây chúng ta sẽ tạo một code có thể sử dụng được 10 lần và không có giới hạn về thời gian. Dĩ nhiên sau khi sử dụng 10 lần thì code này sẽ bị mất hiệu lực:

Doorman::generate()->uses(10)->make();

Nếu chúng ta muốn giới hạn thời gian sử dụng của code, chúng ta sử dụng ->expiresOn():

$date = Carbon::now('UTC')->addDays(7);
Doorman::generate()->expiresOn($date)->make();

Ở trên chúng ta tạo một code sẽ bị hết hạn vào 1 ngày cố định (7 ngày kể từ ngày tạo). Còn nếu chúng ta không muốn tính toán ngày mà nó sẽ hết hạn mà chỉ muốn nó hết hạn sau một số ngày cố định nào đó, ví dụ chúng ta tạo 1 code hết hạn sau 14 ngày kể từ ngày hôm nay:

Doorman::generate()->expiresIn(14)->make();

Ngoài ra chúng ta có thể tạo code cho một email cố định nào đó và chỉ có email này mới có thể sử dụng nó:

Doorman::generate()->for('[email protected]')->make();

Redeem Invites

Chúng ta có thể lấy lại code bằng gọi phương thức redeem(). Tham số truyền vào phương thức này là codeemail (email là tham số tùy chọn, có thể có hoặc không). Note: mình sẽ dùng redeem thay cho việc dịch nó sang tiếng Việt cho đồng nhất với tên phương thức

Doorman::redeem('ABCDE');
// or
Doorman::redeem('ABCDE', '[email protected]');

Nếu Doorman có thể redeem code thì nó sẽ tăng số lần sử dụng của code lên 1, nếu không thì nó sẽ throw một exception. Dưới đây là danh sách các ExceptionDoorman có thể throw:

  • InvalidInviteCode Nếu code không tồn tại trong cơ sở dữ liệu.
  • ExpiredInviteCode Nếu code đã hết hạn sử dụng (theo thời gian).
  • MaxUsesReached Nếu code đã hết số lần sử dụng tối đa.
  • NotYourInviteCode Nếu code đó chỉ dành cho một email nào đó mà không phải dành cho bạn.

Các exceptions ở trên được extend từ DoormanException vậy nên bạn có thể sử dụng DoormanException để bắt các exception được throw thay vì nhớ các exceptions ở trên:

try {
    Doorman::redeem(request()->get('code'), request()->get('email'));
} catch (DoormanException $e) {
    return response()->json(['error' => $e->getMessage()], 422);
}

Check Invites without redeeming them

Chúng ta có thể kiểm tra một code bằng cách gọi phương thức check. Phương thức này nhận các tham số tương tự với phương thức redeem ở trên. Nó sẽ trả về true hoặc false thay vì throw exception như redeem:

Doorman::check('ABCDE');
// or
Doorman::check('ABCDE', '[email protected]');

Translation support

Bạn có thể thay đổi các message được trả về từ doorman để hỗ trợ đa ngôn ngữ hoặc theo ý của bạn. Chúng ta cần publish file language của doorman:

$ php artisan vendor:publish --tag=translations

File language sẽ được export vào thư mục /resources/lang/vendor/doorman/en và bạn có thể edit file messages.php. Nếu bạn muốn hỗ trợ nhiều ngôn thữ thì có thể tạo thêm folder chứa ngôn ngữ mà bạn muốn (ví dụ: vi) và đặt thêm file messages.php trong nó /resources/lang/vendor/doorman/vi. Tham khảo thêm tại.

Validation

Nếu bạn muốn xác nhận code trước khi bạn redeem nó hoặc sử dụng Form Requests thì bạn có thể sử dụng validate như dưới đây:

public function store(Request $request)
{
    $this->validate($request, [
        'email' => 'required|email|unique:users',
        'code' => 'required|doorman:email',
    ]);

    // Add the user to the database.
}

Doorman đã extend thêm một ruledoorman và bạn có thể sử dụng nó như các rules có sẵn trong Laravel. Ở ví dụ trên, :email là phần không bắt buộc phải có và nó sẽ được truyền vào phương thức Doorman::check. Tên của trường sau dấu : là tên của cột email trong request, (nó có thể là email hoặc email_address etc).

Config

Để chỉnh sửa config mặc định của doorman, trước hết bạn phải publish file config của nó:

$ php artisan vendor:publish --tag=config

trong file config/doorman.php bạn sẽ thấy:

return [
    'invite_table_name' => 'invites',
];

If you change the table name and then run your migrations Doorman will then use the new table name. Bạn có thể đổi tên của bảng chứa thông tin invites và chạy migrations, Doorman sẽ sử dụng tên mới của bảng.

Console

To remove used and expired invites you can use the cleanup command: Bạn có thể xóa các code đã hế hạn sử dụng bằng cách sử dụng command: cleanup

$ php artisan doorman:cleanup