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. 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) |
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 Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
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:
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.
Muốn so sánh dữ liệu từ dưới database với này thì làm sao ạ, của em nó hiện lỗi là "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'u363514560_sept7.users' doesn't exist (SQL: select * from
users
whereemail
= binhtran@gmail.com limit 1 em không biết fix sao :((