Laravel Authentication xác thực người dùng thật đơn giản

Trong các hệ thống website đang hoạt động trên Internet, một tính năng không thể thiếu là xác thực người dùng. Tính năng này giúp các website biết được ai đang sử dụng hệ thống để điều hướng thành viên đến các nguồn tài nguyên khác nhau, ngoài ra nó bảo mật thông tin khác nhau với các nhóm thành viên khác nhau. Trước đây, để viết một tính năng xác thực người dùng là mất rất nhiều công sức, nhưng Laravel đã làm mọi việc trở nên thật đơn giản.

Các thiết lập cấu hình trong Laravel Authentication

Laravel đã tạo sẵn các Controller, View, Middleware, Model… và cả file cấu hình config/auth.php để chúng ta chỉ cần thiết lập là có thể chạy được ngay.

Config/auth.php thiết lập cấu hình Laravel Authentication

Đầu tiên, chúng ta sẽ đi vào file thiết lập cấu hình config/auth.php để xem có những gì cần cài đặt khi chạy Laravel Authentication:

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

Trong file này có hai phần cần quan tâm là guards và providers, guards định nghĩa cách thức xác thực người dùng cho các request, mặc định guards sử dụng Laravel Session để lưu trữ các thông tin trạng thái. Providers định nghĩa các cách thức lưu trữ và lấy dữ liệu để xác thực người dùng. Laravel hỗ trợ hai cách thức là Laravel Eloquent ORM hoặc Laravel Query Builder để tương tác với CSDL trong xác thực, ngoài ra nó cũng cho phép định nghĩa riêng các providers của chính bạn để sử dụng, tuy nhiên chúng ta có lựa chọn các cách thức mặc định này là đã đáp ứng rất tốt cho ứng dụng web.

Các Model, View, Controller tạo sẵn cho Laravel Authentication

Tiếp theo, chúng ta sẽ xem xét các thành phần được tạo ra sẵn trong Laravel để phục vụ cho việc xác thực. Mặc định một Eloquent Model app\User.php được tạo ra, model này được sử dụng mặc định trong file cấu hình config/auth.php. Có một số chú ý khi tạo bảng users tương ứng trong CSDL: cột password phải có độ dài ít nhất là 60 ký tự, phải có cột remember_token với độ dài 100 ký tự và có thể null, cột này sử dụng cho tùy chọn nhớ xác thực trong form xác thực.

Laravel cũng tạo ra một loạt các Controller trong app\Http\Controllers\Auth như:

  • RegisterController: Quản lý việc đăng ký thành viên mới.
  • LoginController: Quản lý việc đăng nhập các thành viên.
  • ForgotPasswordController: gửi email với đường link sử dụng cho reset password.
  • ResetPasswordController: kiểm soát việc reset mật khẩu với các logic do lập trình viên thêm vào.

Với phần lớn các ứng dụng web, các Controller ở trên không cần thay đổi gì.

Các view sử dụng trong Laravel Authentication cũng được tạo ra sẵn nằm trong thư mục resources/views/auth.

Tạo ứng dụng web có xác thực bằng Laravel Authentication

Ok, chúng ta đã dông dài một chút, giờ chúng ta sẽ bắt tay thêm tính năng xác thực người dùng vào ứng dụng web có sẵn trong các bài viết trước trong allaravel.com hoặc bạn xem lại Cách cài đặt môi trường test cho Laravel.

Cài đặt thiết lập Laravel Authentication

Đầu tiên, chúng ta sử dụng lệnh artisan sau để tạo ra các thành phần, các cấu hình mặc định sử dụng trong Laravel authentication.

c:\xampp\htdocs\laravel-test>php artisan make:auth
Authentication scaffolding generated successfully.

Câu lệnh trên cũng thêm một số route vào routes/web.php. Tiếp theo đó chúng ta sử dụng Laravel Migrate để tạo các bảng liên quan trong CSDL. Chú ý: do trong bài Làm việc với CSDL trong Laravel chúng ta có một ví dụ đơn giản về cách xác thực và làm việc với CSDL, ví dụ đã tạo ra bảng users trong database do đó nếu chúng ta chạy lệnh artisan migrate nó sẽ báo lỗi rằng bảng users đã tồn tại.

c:\xampp\htdocs\laravel-test>php artisan migrate
Migration table created successfully.


  [Illuminate\Database\QueryException]
  SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' alre
  ady exists (SQL: create table `users` (`id` int unsigned not null auto_incr
  ement primary key, `name` varchar(255) not null, `email` varchar(255) not n
  ull, `password` varchar(255) not null, `remember_token` varchar(100) null,
  `created_at` timestamp null, `updated_at` timestamp null) default character
   set utf8mb4 collate utf8mb4_unicode_ci)



  [PDOException]
  SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' alre
  ady exists

Chúng ta có thể xóa bảng users này đi để chạy lại lệnh artisan hoặc chúng ta thêm các yêu cầu trên các cột như ở phần đầu bài viết, thêm cột remember_token. Ở đây, tôi thực hiện xóa bảng users đã có và chạy lại lệnh php artisan migrate.

c:\xampp\htdocs\laravel-test>php artisan migrate
Migration table created successfully.


  [Illuminate\Database\QueryException]
  SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
  oo long; max key length is 767 bytes (SQL: alter table `users` add unique `
  users_email_unique`(`email`))



  [PDOException]
  SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
  oo long; max key length is 767 bytes

Oạch, vẫn lỗi nhưng lần này lỗi khác liên quan đến độ dài tối đa của key. Sau một hồi tìm hiểu, lỗi này là do Laravel 5.4 đã thay đổi character set mặc định sang utf8mb4 để hỗ trợ việc lưu trữ emojis (một đoạn ký tự sắp xếp thành hình biểu cảm, ví dụ (^o^)      (^_-)      ┐(´~`)┌). Lỗi này sẽ xảy ra khi bạn sử dụng mySQL phiên bản 5.7.7 trở xuống. Để sửa lỗi này, bạn sửa lại file AppServiceProvider.php nằm trong thư mục app\Providers

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Schema;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Schema::defaultStringLength(191);
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Ok, giờ chạy lại php artisan migrate và mọi chuyện đã rất ổn.

c:\xampp\htdocs\laravel-test>php artisan migrate
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table

Quá trình migrate trên tạo ra hai bảng là users và password_reset trong CSDL laravel-test.

Như vậy, ứng dụng của chúng ta đã cài đặt xong tính năng xác thực người dùng. Chúng ta sẽ kiểm tra xem nó hoạt động như thế nào, do trong users hiện chưa có bản ghi nào, nên chưa có user nào đăng nhập được, bạn cần đăng ký một tài khoản trước đã. Vào http://laravel.dev/register

Man hinh dang ky mac dinh trong Laravel authentication

Có rất nhiều route được tạo ra khi bạn chạy Laravel Authentication, để biết được các route nào được thêm vào sử dụng lệnh

// Sử dụng cho phiên bản Laravel 4 trở xuống
php artisan routes

// Sử dụng cho Laravel 5
php artisan route:list

Chúng ta sẽ thấy một số đường dẫn cơ bản như sau:

  • http://laravel.dev/login: sử dụng cho đăng nhập
  • http://laravel.dev/logout: sử dụng để đăng xuất
  • http://laravel.dev/register: sử dụng để đăng ký thành viên.
  • http://laravel.dev/password/email: gửi email reset mật khẩu.
  • http://laravel.dev/password/reset/{token}: đường link gửi trong email reset mật khẩu.
  • http://laravel.dev/password/reset: form reset mật khẩu.

Ok, giờ tạm nghỉ 10 phút cho bạn khám phá tính năng Laravel Authentication. Đầu tiên, đăng ký một tài khoản, sau đó thực hiện đăng nhập, đăng xuất…

Bạn thấy đấy, việc cài đặt sử dụng Laravel authentication thật đơn giản phải không. Tiếp theo chúng ta sẽ đi sâu hơn chút các công việc như: chỉnh sửa lại các giao diện mặc định, thiết lập xác thực cho các đường dẫn cần xác thực.

Chỉnh sửa giao diện mặc định trong Laravel Authentication

Chúng ta cần sửa lại giao diện mặc định trong xác thực người dùng để phù hợp với giao diện chung toàn bộ website. Tất cả các view mặc định của Laravel Authentication đều nằm trong resources/views/auth. Đầu tiên chúng ta sẽ điều chỉnh trang đăng nhập login.blade.php trong thư mục trên.

@extends('layouts.default')

@section('title', 'Đăng nhập - Allaravel.com')

@section('content')
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Đăng nhập</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form" method="POST" action="{{ route('login') }}">
                        {{ csrf_field() }}

                        <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                            <label for="email" class="col-md-4 control-label">Địa chỉ email</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>

                                @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
                            <label for="password" class="col-md-4 control-label">Mật khẩu</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control" name="password" required>

                                @if ($errors->has('password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Ghi nhớ mật khẩu
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-8 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Đăng nhập
                                </button>

                                <a class="btn btn-link" href="{{ route('password.request') }}">
                                    Quên mật khẩu?
                                </a>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
@endsection

Chúng ta đưa blade template mặc định vào cho trang login @extends(‘layouts.default’), xem lại Laravel Blade xây dựng giao diện module hóa. Giờ chúng ta vào thử http://laravel.dev/login xem giao diện như thế nào.

Trang đăng nhập đã cá nhân hóa trong Laravel Authentication

Hehe, nhìn khá hơn đấy chứ. Với các view còn lại bạn tự thực hành nhé, code của toàn bộ các view đã thay đổi tôi sẽ đưa vào cuối bài, bạn có thể tải về để thực hành.

Thiết lập xác thực cho các URL yêu cầu xác thực

Chúng ta đã đi qua được quá nửa chặng đường, tiếp theo chúng ta xem cách thức thiết lập xác thực cho các đường dẫn yêu cầu. Quay lại với ví dụ quản lý sản phẩm trong Xây dựng truy vấn bằng Laravel Query Builder, phần này cho phép tạo mới, chỉnh sửa, quản lý danh sách các sản phẩm, đây là tính năng dành cho quản trị viên, do đó chúng ta yêu cầu phải xác thực người dùng mới được sử dụng phần quản trị sản phẩm.

Trong ví dụ này, đường dẫn của phần quản trị là http://laravel.dev/product, nên chuyển sang http://laravel.dev/admin/product để quy hoạch lại, tất cả những gì cần quản trị sẽ đưa vào http://laravel.dev/admin. Laravel Authentication đã tạo ra một Middleware là auth (xem thêm Laravel Middleware) dùng để xác thực người dùng, chúng ta chỉ việc sử dụng middleware này trong các route.

Route::resource('admin/product', 'ProductController', [
	'only' => ['create', 'store', 'edit'],
	'middleware' => 'auth'
]);

bạn có thể xem auth đăng ký như thế nào tại app\Http\Kernel.php trong phần routeMiddleware.

Giờ bạn vào lại thử trang quản lý danh sách sản phẩm http://laravel.dev/admin/product nếu chưa đăng nhập nó sẽ tự động chuyển hướng đến trang đăng nhập http://laravel.dev/login. Bạn thực hiện đăng nhập xong sẽ vào lại trang danh sách bình thường.

Lời kết

Laravel Authentication thật sự rất đơn giản, tích hợp nhanh vào các ứng dụng web đòi hỏi phải xác thực. Chúng ta còn rất nhiều điều cần tìm hiểu thêm nữa về xác thực người dùng như sử dụng ajax kết hợp với Laravel Authentication để xác thực, một tính năng cũng được các trang web sử dụng nhiều hiện nay là xác thực người dùng bằng sử dụng các mạng xã hội… Tất cả những vấn đề này chúng ta sẽ quay lại trong các bài viết tiếp theo, các bạn đón xem nhé.

15 thoughts on “Laravel Authentication xác thực người dùng thật đơn giản

  1. Laravel Authentication mặc định sử dụng email để xác thực người dùng, có thể xác thực theo kiểu hoặc nhập email hoặc nhập username hoặc thậm chí cả số điện thoại được không, các website giờ toàn dùng nhiều tùy chọn cho người dùng dễ nhớ, anh em chỉ giúp mình với.

    1. Hoàn toàn có thể sử dụng bất kỳ một thông tin khác của người dùng để xác thực như số điện thoại, username, email… và hiện nay còn có thể tích hợp các mạng xã hội như Facebook, Google+, Twitter, GitHub… để xác thực người dùng. Mình đang tập trung hoàn thành nội dung Khóa học Laravel cơ bản 7 ngày nên chưa có thời gian cho các bài viết khai thác sâu hơn trong Laravel.

  2. Có cách nào xác thực hai bước bằng tin nhắn trong Laravel không các bác, đang cần gấp bác nào giúp em với

  3. em thấy nhiều website đặc biệt là các diễn đàn thường bắt người dùng phải bấm vào một đường dẫn xác thực trong email thì mới bắt đầu sử dụng được tài khoản đăng ký, có bác nào biết không giúp em với

  4. Nếu giả sử em muốn thay tạo thêm một bảng như User thì chỉ cần cấu hình nó trong config/auth.php thôi phải không?

    1. Ý bạn là tạo một bảng khác để lưu trữ thông tin người dùng và xác thực bằng bảng này đúng không? bạn có thể cấu hình trong file config/auth.php như bạn đã nêu ở trên trong phần:
      ‘providers’ => [
      ‘users’ => [
      ‘driver’ => ‘eloquent’,
      ‘model’ => App\User::class,
      ],
      ],

  5. Ngô Văn Thoại

    - Edit

    Reply

    Theo mình cái xóa delete khi update thêm cột hay xóa cột khi bị sinh lỗi : sqlstate 42s01 base table or view already exists 1050 table ‘users’ already exists
    Là quá dở,
    Vì khi dữ liệu nhiều, xóa đi là mất dữ liệu,

    1. Chào Thoại, do lúc đầu mình định viết thành các bài viết rời rạc không liên quan, nhưng được khoảng 3-4 bài thì mình mới nảy sinh ý định tạo thành một series “Học Laravel miễn phí“, lúc đầu tạo bảng users bằng tay, sau đó đến phần Laravel Authentication hệ thống lại tạo ra bảng users nữa dẫn đến lỗi như bạn mô tả. Có thời gian mình sẽ điều chỉnh lại bài viết đầu.

  6. Help help, mình muốn thêm một trường active trong bảng users, khi active = 1 thì người dùng mới đăng nhập được hệ thống, active = 0 thì không cho đăng nhập. Ai giúp với, đang cần gấp !!!!!!!!!!!

    1. Trong Laravel 5.4 bạn chỉ cần override phương thức credentials trong app\Http\Controller\Auth\LoginController.php như sau:
      protected function credentials(\Illuminate\Http\Request $request)
      {
      return [’email’ => $request->{$this->username()}, ‘password’ => $request->password, ‘active’ => 1];
      }
      Nhớ thêm cột active vào bảng users.

  7. Xác thực người dùng bằng Laravel Authentication là rất đơn giản rồi nhưng còn phần phân quyền, ad có thể viết thêm bài về phần phân quyền không? Minh đang rất cần kiến thức phân quyền người dùng trong Laravel. Thanks.

Add Comment