07/09/2018, 10:18

Xác Thực Người Dùng Trong Laravel

Xác thực người dùng là việc kiểm tra xem người dùng đang truy cập vào website đã đăng ký tài khoản trên trang web hay chưa. Quy trình này được thực hiện bằng cách yêu cầu người dùng cung cấp thông tin cá nhân thông thường là địa chỉ email và mật khẩu để có thể truy cập vào một số trang nhất định. ...

Xác thực người dùng là việc kiểm tra xem người dùng đang truy cập vào website đã đăng ký tài khoản trên trang web hay chưa. Quy trình này được thực hiện bằng cách yêu cầu người dùng cung cấp thông tin cá nhân thông thường là địa chỉ email và mật khẩu để có thể truy cập vào một số trang nhất định. Bài học này sẽ hướng dẫn bạn thực hiện việc xác thực người dùng sử dụng Laravel Framework. Các ví dụ của bài học này được viết sử dụng phiên bản 4.2, tuy nhiên với các phiên bản mới nhất là 5.2 các đoạn mã này cũng sẽ được viết theo cách tương tự.

Thiết Kế Database

Để đơn giản hóa, database của chúng ta chỉ bao gồm 1 bảng có tên là users dùng để lưu thông tin người dùng đăng nhập vào ứng dụng. Bảng này sẽ có 4 trường như sau:

Tên trường Kiểu dữ liệu
first_name varchar(255)
last_name varchar(255)
email varchar(255)
password varchar(255)

Migrate Database

Tiếp theo chúng ta sẽ migrate database sử dụng gói thư viện Laravel Generators. Sau khi cài đặt Laravel Generators bạn mở terminal và đi tới thư mục dự án và chạy câu lệnh sau:

$ php artisan generate:migration create_users_table --fields="first_name:string, last_name:string, email:string, password:string"

Kết thúc câu lệnh trên bạn sẽ thấy một file với tên 2015_10_07_134728_create_users_table.php được tạo bên trong thư mục app/database/migrations (phần ngày tháng năm trong tên của file migration được tạo ra trên máy bạn có thể sẽ khác với của tôi). Khi mở file này trên text editor bạn sẽ thấy trong phương thức up đoạn code như sau:

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

Tạo Database

Tiếp theo chúng ta sẽ tạo một databse cho ứng dụng với tên là laravel_authentication. Trên terminal bạn chạy câu lệnh sau để kết nối với MySQL database server:

$ mysql -u root -p

Nếu bạn đã thay đổi mật khẩu cho root bạn cần nhập mật khẩu cho root. Sau khi đăng nhập thành công vào MySQL database server bạn chạy câu lệnh sau:

> create database laravel_authentication;

Cấu Hình Database Trong Ứng Dụng

Bây giờ sau khi bạn đã tạo xong database chúng ta cần cập nhật cấu hình ứng dụng để sử dụng database mới được tạo ra. Mở file app/database/migrations/database.php và tìm tới dòng 55 bạn sẽ thấy đoạn mã giống như phía dưới:

'mysql' => array(
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'forge',
    'username'  => 'forge',
    'password'  => ',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => ',
),

Trong mảng này bạn cần thay đổi giá trị của khóa database thành laravel_authentication, khóa username thành root và khóa password là mật khẩu đăng nhập cho root.

Migrate Database

Bây giờ chúng ta cần tạo bảng users sử dụng file migrations mới được tạo ở trên. Quá trình này được gọi là migrate cơ sở dữ liệu. Với Laravel chúng ta chỉ cần 1 câu lệnh trên terminal sử dụng artisan để thực hiện việc này:

$ php artisan migrate

Nhập vào yes hoặc y, khi bạn thấy trên màn hình hiển thị thống báo xác nhận việc chạy migration:

**************************************
*     Application In Production!     *
**************************************

Do you really wish to run this command? y
Migration table created successfully.
Migrated: 2015_10_07_134728_create_users_table

Sau khi câu lệnh trên kết thúc bạn sẽ thấy trên database laravel_authentication của chúng ta có bảng users.

Tạo Model

Tiếp theo chúng ta sẽ tạo User model để tương tác với bảng users trên database. Để tạo model chúng ta có thể sử dụng công cụ Laravel Generator. Trên terminal đi tới thư mục dự án và chạy câu lệnh sau:

$ php artisan generate:model User

Bạn sẽ thấy có một thông báo lỗi hiện lên nói rằng User model đã được tạo ra. Điều này là bởi vì khi tạo dự án Laravel cũng tự động tạo model User cho bạn và mặc dù chúng ta có thể sử dụng model này vào bài học này tôi muốn bạn làm lại công việc tạo User model này từ đầu để có thể hiểu rõ hơn hoạt động của nó.

Xóa file User.php ở trong thư mục app/models và chạy lại câu lệnh generate ở trên bạn sẽ thấy file User.php bây giờ ngắn hơn rất nhiều:

<?php

class User extends Eloquent {
    protected $fillable = [];
}

Ở trên bạn cũng sẽ không thấy có dòng lệnh sau:

protected $table = 'users';

Khi thuộc tính $table không có trong model thì Laravel sẽ tự động lấy tên table bằng cách chuyển tên của model về chữ in thường và thêm chữ s vào sau đó.

Tuy nhiên để có thể xác thực được người dùng chúng ta cần kế thừa lớp UserInterface, lớp này cung cấp các phương thức cho phép chúng ta dễ dàng kiểm tra thông tin người dùng cung cấp với dữ liệu trên database chỉ với 1 câu lệnh duy nhất Auth::attempt() mà bạn sẽ thấy ở phần tiếp ngay sau đây. Cập nhật User model như dưới đây:

<?php

use IlluminateAuthUserTrait;
use IlluminateAuthUserInterface;

class User extends Eloquent implements UserInterface {
    use UserTrait;

    protected $fillable = [];
}

Tạo Dữ Liệu Seed

Tạo dữ liệu Seed là việc chèn thêm một vài dữ liệu mẫu cho các bảng trên CSDL. Để tạo dữ liệu seed trước tiên chúng ta tạo một file php Seeder, sử dụng terminal và câu lệnh sau:

$ php artisan generate:seed users

Câu lệnh trên sẽ tạo ra file UsersTableSeeder.php trong thư mục app/database/seeds/. Tuy nhiên chúng ta cũng sẽ cần thay đổi nội dung của file trên thành như dưới đây:

<?php

class UsersTableSeeder extends Seeder {

    public function run()
    {
        DB::table('users')->delete();
        User::create(array(
            'first_name' => 'John',
            'last_name' => 'Doe',
            'email' => 'johndoe@example.net',
            'password' => 'mypass',
        ));
    }

}

Ở trên chúng ta thấy trong phương thức run có sử dụng câu lệnh sau dùng để xóa dữ liệu trên bảng users:

DB::table('users')->delete();

Và sau đó chúng ta sử dụng method User::create() với đối số truyền vào là một mảng chứa thông tin của một record mẫu để chèn dữ liệu vào bảng.

Tiếp theo, để seed dữ liệu vào bảng bạn mở file app/database/seeds/DatabaseSeeder.php và tìm tới phương thức run() và thêm dòng lệnh dưới đây:

$this->call('UsersTableSeeder');

Sau đó, quay trở lại terminal và chạy câu lệnh sau:

$ php artisan db:seed

Kết thúc câu lệnh trên bạn kiểm tra trên CSDL sẽ thấy một record được thêm vào. Banj có thể kiểm tra record mới được thêm vào sử dụng công cụ như PHPMyAdmin:

Laravel Seed Database

Tạo View

Ở phần này chúng ta sẽ tạo 2 view khác nhau một file login.php là trang dùng để người dùng chưa đăng nhập vào hệt thống có thể thực hiện việc đăng nhập và một file index.php dành cho những người dùng đã đăng nhập vào hệ thống.

Sử dụng text editor của bạn và tạo file login.php bên trong thư mục app/views với nội dung như sau:

<form method="POST" action="login">
    <div class="form-group">
        <label>Email:</label>
        <input class="form-control" type="text" name="email">
    </div>

    <div class="form-group">
        <label>Password:</label>
        <input class="form-control" type="password" name="password">
    </div>

    <button class="btn btn-primary">Submit</button>
</form>

Tiếp theo cũng trong thư mục của file mới tạo ra, bạn tạo thêm một file index.php với nội dung như sau:

<h1>Hello user</h1>

Định Nghĩa Route

Tiếp theo sau khi tạo xong view chúng ta cần phải định nghĩa các route tương ứng để có thể sử dụng các view mới tạo ra ở trên. Trong file app/routes.php bạn thêm vào đoạn mã sau:

Route::get('/', 'HomeController@index');
Route::post('/login', 'HomeController@login');

Ở trên chúng ta định nghĩa 2 route cho ứng dụng. Với route thứ nhất các yêu cầu gửi tới webserver theo giao thức GET dưới đường dẫn http://localhost/laravel_authenticate/ sẽ được xử lý bởi phương thức index trong file app/controllers/HomeController.php. Tương tự, route thứ 2 quy định việc các yêu cầu gửi tới webserver theo giao thức POST dưới địa chỉ URL http://localhost/laravel_authenticate/login sẽ được xử lý bởi phương thức authenticate trong trong file app/controllers/HomeController.php.

Controller

Bước tiếp theo chúng ta cần thực hiện là định nghĩa 2 phương thức index và login trong HomeController.php. Mở file này lên và thêm đoạn mã sau vào phía cuối file:

function index () {
    if (Auth::check())
    {
        // Người dùng đã đăng nhập
    } else {
        return View::make('login');
    }
}

Ở trên chúng ta sử dụng cấu trúc điều khiển và kiểm tra giá trị trả về từ việc gọi phương thức Auth::check() để xác định xem người dùng đã đăng nhập hay chưa. Trường hợp nếu người dùng đã đăng nhập (giá trị của Auth::check() trả về là true) chúng ta sẽ trả về nội dung có trong file index.php sử dụng phương thức tính View::make():

if (Auth::check()) {
    // Người dùng đã đăng nhập
    return View::make('index');
}

Trường hợp người dùng chưa đăng nhập chúng ta sẽ trả về nội dung file login.php:

return View::make('login');

Bây giờ nếu bạn mở trình duyệt và truy cập vào địa chỉ trang index thì trình duyệt sẽ ngay lập tức chuyển tiếp bạn tới trang login để đăng nhập.

Và cuối cùng để xác thực người dùng, chúng ta sẽ thêm phương thức login như dưới đây vào cuối file HomeController.php:

function login() {

    $email = Input::get('email');
    $password = Input::get('password');

    if (Auth::attempt(array('email' => $email, 'password' => $password)))
    {
        return Redirect::to('/index');
    } else {
        return Redirect::to('/login');
    }
}

Ở trên chúng ta sử dụng phương thức Input::get() để lấy ra các giá trị của các trường trong biểu mẫu mà người dùng nhập vào và gửi lên server:

$email = Input::get('email');
$password = Input::get('password');

Tiếp theo, phương thức Auth::attempt() được gọi với đối số truyền vào là một mảng truyền với 2 khóa email và password là giá trị của 2 trường tương ứng trong biểu mẫu mà chúng ta vừa mới lấy ra. Phương thức này sẽ thực hiện việc so sánh giá trị người dùng gửi lên với giá trị các trường tương ứng có trên cơ sở dữ liệu:

if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
   //....
}

Nếu giá trị trả về là true chúng ta sẽ chuyển tiếp người dùng về route index:

 return Redirect::to('/index');

Ngược lại chúng ta sẽ chuyển tiếp người dùng về route login:

return Redirect::to('/login');

Như vậy tới đây bạn đã hoàn tất quy trình xác thực người dùng trong Laravel 4.2.

0