[Authenticate and Authorize in Laravel] Chương 1: Model và Controller dùng để authenticate.

Spread the love

[Authenticate and Authorize in Laravel] Chương 1: Model và Controller dùng để authenticate.

Mỗi khi tạo một application, chúng ta cần phải tạo hệ thống authenticate / authorize người dùng, bao gồm: đăng kí, login, sessions, reset mật khẩu, và cho phép truy cập một resources nào đó. Tất nhiên đây là một việc khá tốn thời gian và khó khăn. May mắn thay Laravel đã built-in sẵn một hệ thống Authentication và Authorization cực mạnh (chỉ có điều chúng ta chưa biết sử dụng chúng như thế nào ). Hôm nay chúng ta sẽ thử tìm hiểu cách laravel – Authentication User – Model dùng để Authentication – Các controller liên quan đến authentication – Middleware – Guards – Authentication events – Authorization User – Authorization Control List (ACL) và Roles – Gate facade – Authorize Middleware – Controller Authorization – Policies

Do nội dung tìm hiểu lần này khá lớn nên chúng ta sẽ tìm hiểu thông qua series: “Laravel authentication and authorization under the hood.”

User Model và Migration

Trước tiên chúng ta thử tìm hiểu về model dùng để Authentication, model User Chúng ta confirm file databases\migrations\create_table_user.php có nội dung như bên dưới

        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

Ta thấy User default được Laravel tạo ra bao gồm: id (tự động tăng), name, email, password, field rememberToken dùng để ghi nhớ user và timestamps lưu thời gian tạo record, và thời gian cuối cùng khi update record.

Tuy nhiên User model bản thân có vẻ đơn giản nhưng lớp cha của nó Illuminate\Foundation\Auth\User cũng khá phức tạp, khi dùng khá nhiều traits. Bao gồm – Authenticatable – Authorizable – CanResetPassword

Vậy thì chúng ta rút ra được điều gì ? Ta có thể nhận thấy – User chúng ta tồn tại trong bảng users ở đó ta có thể điền thông tin name, email, password , ngoài ra còn có thể ghi nhớ user thông qua trường rememberToken – Chúng ta có thể sử dụng các traits trên không chỉ là cho class User chúng ta hoàn toàn có thể sử dụng cho một class khác nếu chúng ta muốn. – Authenticatable traits: chứa các methods cho phép framework authenticate một instance của class User với hệ thống. Trait Authenticatable chứa các hàm cần thiết để validate một Eloquent model để check quyền login vào hệ thống. – Authorizable trait: chứa các methods cancannot dùng để check xem một user có quyền thực hiện một thao tác liên quan đến một resouces/assets nào không? – CanResetPassword trait: với method getEmailForPasswordReset() cho phép framework reset password của bất kì thực thể nào thoả mãn contract.

Như vậy laravel đã cung cấp cho chúng ta các tools cơ bản để: tạo User và lưu vào DB, check xem User có thể login hay không đồng thời phân quyền cho từng User tương ứng

Sử dụng auth() global helper và Auth facade

auth() global helper là phương pháp nhanh nhất để chúng ta tương tác với laravel authentication system. Trong đó: – auth()->check(): kiểm tra xem user có đang login hay không – auth()->guest(): trả về kết quả là true nếu user đang là guest (chưa login) – auth()->user() hoặc auth()->id() : trả về kết quả là eloquent model của user đang login hoặc chỉ là id của User đang login trong hệ thống.

Chúng ta có thể sử dụng auth() global helper như đoạn code mẫu bên dưới

public function dashboard(){
    if (auth()->guest()){
        return redirect()->to('/login')
    }

    return views('user.dashboard')->with('user', auth()->user());
}

Auth Controllers

Chúng ta thử đi tìm hiểu một lượt các controllers được Laravel tạo sẵn cho chúng ta khi chúng ta chạy xong câu lệnh php artisan make:auth Chúng bao gồm RegisterController , LoginController . ResetPasswordController

Register Controllers

Register controller, như cái tên của nó, chịu trách nhiệm – Hiển thị view cho phép người dùng đăng kí thông tin và save vào DB – Chúng ta có thể validate thông tin người dùng đã nhập (ví dụ như email có đúng không, password constraints như thế nào) – Thiết lập sẽ redirect về đâu sau khi đăng kí thành công thông qua thuộc tính $redirectTo

class RegisterController extends Controller{
    use RegistersUsers;
    protected $redirectTo = '/home';
    protected function validator(array $data){
        return Validator::make($data, [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]); 
    }
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }}

Ta có thể thấy class RegisterController sử dụng trait RegistersUserTrait để hiển thị form đăng kí (nếu chúng ta muốn hiển thị một form khác chúng ta có thể override method : showRegistrationForm() và cho trả về một view khác)

//RegistersUserTrait
    public function showRegistrationForm()
    {
        return view('auth.register'); //Override view để hiện thị form đăng kí. Default là auth.register view
    }
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        event(new Registered($user = $this->create($request->all())));

        $this->guard()->login($user);

        return $this->registered($request, $user)
                        ?: redirect($this->redirectPath());
    }

Sau đó trait này có hàm register() nhận nhiệm vụ validate thông tin input của User (kiểm tra có thoả mãn các ràng buộc nhập liệu không) sau đó sẽ tạo User (thông qua hàm create() ). Sau đó nếu sẽ login User (thông qua gọi $this->guard()->login) cuối cùng là đến phần redirect chúng ta có thể override redirect (có thể code trong hàm registered hoặc sẽ set trong $redirectTo của controller)

Login Controller

Login controller, tất nhiên làm nhiệm vụ login User vào hệ thống. Ngoài ra nó còn sử dụng trait AuthenticatesUsers trong đó lại có thêm 2 traits con là RedirectUsersThrotllesLogins traits. Giống như class RegisterController , LoginController có thuộc tính $redirectTo để thiết lập sẽ redirect về đâu sau khi login thành công.

Authenticate User traits

Authenticate User trait có nhiệm vụ hiển thị form login, kiểm tra xem thông tin User input có chính xác không, hạn chế số lần login sai liên tục của User, đăng xuất, và redirect user sau khi login thành công. Bao gồm các hàm sau: – showLoginForm() : default hiển thị form login cho User – login(): nhận POST data, validate thông tin và đăng nhập, hàm login() cũng có sử dụng ThottlesLogins trait để chặn User login liên tục sai quá nhiều. Nếu user login thành công họ sẽ được redirect theo path được chỉ định sẵn ở thuộc tính $redirectToauthenticated(): đây là một method trống, sẽ được gọi sau khi login thành công. Chúng ta có thể override hàm này ở tại LoginController nếu muốn. – Chúng ta cũng có thể define lại username() . username() là một hàm trong AuthenticatesUsers trait ở đó định nghĩa column nào dùng để hiện thị tên của User (default đang là cột email). – Ta cũng có thể sử dụng một guard khác khi authenticate User thông qua việc override hàm guard() trong AuthenticatesUsers

ThrottlesLogins traits

ThrottlesLogins traits có nhiệm vụ ngăn chặn, giới hạn số lần login sai quá nhiều của User. Trait ThrottlesLogins là interface của Illuminate\Cache\RateLimiter class, dùng để giới hạn bất kì event nào thông qua cache. Toàn bộ các methods của ThrottleLogins traits đều là protected vì vậy chúng sẽ không access được trực tiếp. Thật ra khi ta sử dụng trait AuthenticatesUsers chúng ta đã được cấu hình sẵn ThrottleLogins traits. Nhiệm vụ của nó sẽ giới hạn 5 lần login sai bởi cùng 1 IP trong 1 phút. Chúng ta có thể thiết lập lại thông qua việc định nghĩa $maxAttempts$decayMinutes bên trong class LoginController. Ví dụ, muốn thay đổi số lần giới hạn sang 6 lần và 5 phút. Ta có thể settings thành

//LoginController
public $maxAttemps = 6;
public $decayMinutes = 30;

ResetPasswordController

ResetPasswordController sử dụng ResetPasswords traits, trong đó, cung cấp các methods để Validation và màn hình để reset passwords. ResetPasswords traits sử dụng class Illuminate\Auth\Passwords\PasswordBroker để reset password cũng như gửi link cho enduser. Ta có thể customize bằng cách sử dụng một class khác cũng implements Illuminate\Contracts\Auth\PasswordBroker

ForgotPasswordController

Controller này đơn giản sẽ gọi SendsPasswordResetEmails() trait. Nó sẽ hiển thị form để user nhập vào email thông qua showLinkRequestForm() và xử lý POST data từ form thông qua hàm sendResetLinkEmail(). Chúng ta có thể customize broker thông qua việc sử dụng hàm broker()

    /**
     * Get the broker to be used during password reset.
     *
     * @return \Illuminate\Contracts\Auth\PasswordBroker
     */
    public function broker()
    {
        return Password::broker(); //Customize broker của chúng ta ở đây. Broker cần phải implements Illuminate\Contracts\Auth\PasswordBroker
    }

Phần tiếp theo chúng ta sẽ nói về việc scaffold Auth và chức năng rememberMe của Laravel được implements như thế nào.

Leave a Reply

Your email address will not be published. Required fields are marked *