Để tạo chức năng Xác thực tài khoản (Đăng nhập/Đăng xuất; Đăng ký) Auth nhanh. Chúng ta sẽ sử dụng các công cụ có sẵn của Laravel.

Step 1: thực thi câu lệnh

php artisan make:auth
Laravel sẽ tự động thực hiện dùm bạn một số bước ban đầu:

1. Tự động đăng ký các route dành cho việc Xác thực tài khoản trong file routes\web.php

// Gọi hàm đăng ký các route dành cho Quản lý Xác thực tài khoản (Đăng nhập, Đăng xuất, Đăng ký)
// các route trong file `vendor\laravel\framework\src\Illuminate\Routing\Router.php`, hàm auth()
Auth::routes();
Danh sách các route Laravel đã đăng ký dùm bạn
+--------+----------+-------------------------+-----------------------+------------------------------------------------------------------------+--------------+
| Domain | Method   | URI                     | Name                  | Action                                                                 | Middleware   |
+--------+----------+-------------------------+-----------------------+------------------------------------------------------------------------+--------------+
|        | GET|HEAD | /                       |                       | Closure                                                                | web          |
|        | GET|HEAD | login                   | login                 | App\Http\Controllers\Auth\LoginController@showLoginForm                | web,guest    |
|        | POST     | login                   |                       | App\Http\Controllers\Auth\LoginController@login                        | web,guest    |
|        | POST     | logout                  | logout                | App\Http\Controllers\Auth\LoginController@logout                       | web          |
|        | POST     | password/email          | password.email        | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web,guest    |
|        | GET|HEAD | password/reset          | password.request      | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest    |
|        | POST     | password/reset          |                       | App\Http\Controllers\Auth\ResetPasswordController@reset                | web,guest    |
|        | GET|HEAD | password/reset/{token}  | password.reset        | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web,guest    |
|        | GET|HEAD | register                | register              | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest    |
|        | POST     | register                |                       | App\Http\Controllers\Auth\RegisterController@register                  | web,guest    |
+--------+----------+-------------------------+-----------------------+------------------------------------------------------------------------+--------------+

2. Tự động tạo các controller để quản lý xử lý logic/nghiệp vụ cho việc Xác thực tài khoản (Auth)

  • app\Http\Controllers\Auth\ForgotPasswordController.php : quản lý các logic/nghiệp vụ cho việc xử lý Quên mật khẩu
  • app\Http\Controllers\Auth\LoginController.php:  quản lý các logic/nghiệp vụ cho việc Đăng nhập
  • app\Http\Controllers\Auth\RegisterController.php: quản lý các logic/nghiệp vụ cho việc Đăng ký
  • app\Http\Controllers\Auth\ResetPasswordController.php: quản lý các logic/nghiệp vụ cho việc reset Mật khẩu

3. Tự động tạo các view tương ứng với chức năng Xác thực tài khoản (Auth)

  • resources\views\layouts\app.blade.php: giao diện layout chủ (master) cho các chức năng Xác thực tài khoản (Auth)
  • resources\views\auth\passwords\email.blade.php: giao diện chức năng Quên mật khẩu (kích hoạt bằng email)
  • resources\views\auth\passwords\reset.blade.php: giao diện chức năng Quên mật khẩu (gởi mật khẩu mới thông qua email)
  • resources\views\auth\login.blade.php: giao diện chức năng Đăng nhập
  • resources\views\auth\register.blade.php: giao diện chức năng Đăng ký

Step 2: tùy chỉnh (customize) chức năng Xác thực tài khoản (Auth) mặc định của Laravel theo ý thích

1. Hiệu chỉnh cấu hình sử dụng model Nhanvien để quản lý việc Xác thực tài khoản

  • Hiệu chỉnh file: config\auth.php
  • Tìm và thay thế đoạn code sau:
/*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        // Không sử dụng model `User` (mặc định của Laravel)
        // 'users' => [
        //     'driver' => 'eloquent',
        //     'model' => App\User::class,
        // ],

        // Thay thế việc Xác thực tài khoản bằng model `Nhanvien`
        'users' => [
            'driver' => 'custom',
            'model' => App\Nhanvien::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],
  • Sau khi hiệu chỉnh config, cần chạy câu lệnh để clear cache config, đảm bảo cho việc đang sử dụng config mới nhất
php artisan config:clear

2. Tạo mới file app\Http\Controllers\Auth\CustomUserProvider.php để custom việc xác thực tài khoản

  • Tạo file app\Http\Controllers\Auth\CustomUserProvider.php
  • Nội dung:
<?php

namespace App\Auth;

use Illuminate\Support\Str;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Auth\UserProvider as UserProviderContract;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;

class CustomUserProvider extends EloquentUserProvider implements UserProviderContract
{
    /**
     * Retrieve a user by their unique identifier.
     *
     * @param  mixed  $identifier
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveById($identifier)
    {
        $model = $this->createModel();

        return $model->newQuery()
            ->where($model->getAuthIdentifierName(), $identifier)
            ->first();
    }

    /**
     * Retrieve a user by their unique identifier and "remember me" token.
     *
     * @param  mixed  $identifier
     * @param  string  $token
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByToken($identifier, $token)
    {
        $model = $this->createModel();

        $model = $model->where($model->getAuthIdentifierName(), $identifier)->first();

        if (! $model) {
            return null;
        }

        $rememberToken = $model->getRememberToken();

        return $rememberToken && hash_equals($rememberToken, $token) ? $model : null;
    }

    /**
     * Update the "remember me" token for the given user in storage.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $token
     * @return void
     */
    public function updateRememberToken(UserContract $user, $token)
    {
        $user->setRememberToken($token);

        $timestamps = $user->timestamps;

        $user->timestamps = false;

        $user->save();

        $user->timestamps = $timestamps;
    }

    /**
     * Retrieve a user by the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByCredentials(array $credentials)
    {
        if (empty($credentials) ||
           (count($credentials) === 1 &&
            array_key_exists('nv_matKhau', $credentials))) {
            return;
        }
        
        // First we will add each credential element to the query as a where clause.
        // Then we can execute the query and, if we found a user, return it in a
        // Eloquent User "model" that will be utilized by the Guard instances.
        $query = $this->createModel()->newQuery();
        

        foreach ($credentials as $key => $value) {
            if (! Str::contains($key, 'nv_matKhau')) {
                $query->where($key, $value);
            }
        }

        return $query->first();
    }

    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials)
    {
        $plain = $credentials['nv_matKhau'];
 
        return $this->hasher->check($plain, $user->getAuthPassword());
    }
}

3. Đăng ký sử dụng CustomUserProvider để đăng nhập

  • Hiệu chỉnh file `app\Providers\AuthServiceProvider.php`
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Auth\CustomUserProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        // Sử dụng CustomUserProvider để xác thực tài khoản
        $this->app->auth->provider('custom', function ($app, array $config) {
            return new CustomUserProvider($app['hash'], $config['model']);
        });
    }
}

4. Hiệu chỉnh LoginController

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/admin'; //Sau khi đăng nhập thành công, sẽ tự động trỏ về trang /admin/

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    /**
     * Hàm trả về tên cột dùng để tìm `Tên đăng nhập`.
     * Thông thường là cột `username` hoặc cột `email`
     */
    public function username(){
        return 'nv_taiKhoan';
    }  

    /**
     * Get the needed authorization credentials from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function credentials(Request $request)
    {
        $cred = $request->only($this->username(), 'nv_matKhau');
        return $cred;
    }

    /**
     * Hàm dùng để Kiểm tra tính hợp lệ của dữ liệu (VALIDATE) khi Xác thực tài khoản
     */
    protected function validateLogin(Request $request)
    {
        $this->validate($request, [
            $this->username() => 'required|string', // tên tài khoản bắt buộc nhập
            'nv_matKhau' => 'required|string',      // mật khẩu bắt buộc nhập
        ]);
    }

    /**
     * Attempt to log the user into the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function attemptLogin(Request $request)
    {
        return $this->guard()->attempt(
            $this->credentials($request), $request->filled('remember')
        );
    }
}

5. Thêm mới cột `nv_ghinhodangnhap` sử dụng migration

  • Thực hiện câu lệnh
php artisan make:migration alter_add_column_v1_to_nhanvien_table --table=cusc_nhanvien
  • Code file `database/migrations/2019_07_05_161859_alter_add_column_v1_to_nhanvien_table.php`
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterAddColumnV1ToNhanvienTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('cusc_nhanvien', function (Blueprint $table) {
            $table->string('nv_ghinhodangnhap')->nullable();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('cusc_nhanvien', function (Blueprint $table) {
            $table->string('nv_ghinhodangnhap');
        });
    }
}
  • Thực thi php artisan migrate để cập nhật cấu trúc database mới.
6. Hiệu chỉnh giao diện Form Đăng nhập
  • Hiệu chỉnh file `resources/views/auth/login.blade.php`
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Login</div>

                <div class="panel-body">
                    <form class="form-horizontal" method="POST" action="{{ route('login') }}">
                        {{ csrf_field() }}

                        <div class="form-group{{ $errors->has('nv_taiKhoan') ? ' has-error' : '' }}">
                            <label for="nv_taiKhoan" class="col-md-4 control-label">Tên tài khoản</label>

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

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

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

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

                                @if ($errors->has('nv_matKhau'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('nv_matKhau') }}</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="nv_ghinhodangnhap" {{ old('nv_ghinhodangnhap') ? 'checked' : '' }}> Ghi nhớ đăng nhập
                                    </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>
</div>
@endsection
7. Hiệu chỉnh model NhanVien
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
class Nhanvien extends Model implements
    AuthenticatableContract
{
    const     CREATED_AT    = 'nv_taoMoi';
    const     UPDATED_AT    = 'nv_capNhat';
    protected $table        = 'cusc_nhanvien';
    protected $fillable     = ['nv_taiKhoan', 'nv_matKhau', 'nv_hoTen', 'nv_gioiTinh', 'nv_email', 'nv_ngaySinh', 'nv_diaChi', 'nv_dienThoai', 'nv_taoMoi', 'nv_capNhat', 'nv_trangThai', 'q_ma'];
    protected $guarded      = ['nv_ma'];
    protected $primaryKey   = 'nv_ma';
    protected $dates        = ['nv_ngaySinh', 'nv_taoMoi', 'nv_capNhat'];
    protected $dateFormat   = 'Y-m-d H:i:s';
    /**
     * Tên cột 'Ghi nhớ đăng nhập'
     * The column name of the "remember me" token.
     *
     * @var string
     */
    protected $rememberTokenName = 'nv_ghinhodangnhap';
    /**
     * Get the name of the unique identifier for the user.
     *
     * @return string
     */
    public function getAuthIdentifierName()
    {
        return $this->getKeyName();
    }
    /**
     * Get the unique identifier for the user.
     *
     * @return mixed
     */
    public function getAuthIdentifier()
    {
        return $this->{$this->getAuthIdentifierName()};
    }
    /**
     * Hàm trả về tên cột dùng để tim `Mật khẩu`
     * Get the password for the user.
     *
     * @return string
     */
    public function getAuthPassword()
    {
        return $this->nv_matKhau;
    }
    /**
     * Hàm dùng để trả về giá trị của cột "nv_ghinhodangnhap" session.
     * Get the token value for the "remember me" session.
     *
     * @return string|null
     */
    public function getRememberToken()
    {
        if (! empty($this->getRememberTokenName())) {
            return (string) $this->{$this->getRememberTokenName()};
        }
    }
    /**
     * Hàm dùng để set giá trị cho cột "nv_ghinhodangnhap" session.
     * Set the token value for the "remember me" session.
     *
     * @param  string  $value
     * @return void
     */
    public function setRememberToken($value)
    {
        if (! empty($this->getRememberTokenName())) {
            $this->{$this->getRememberTokenName()} = $value;
        }
    }
    /**
     * Hàm trả về tên cột dùng để chứa REMEMBER TOKEN
     * Get the column name for the "remember me" token.
     *
     * @return string
     */
    public function getRememberTokenName()
    {
        return $this->rememberTokenName;
    }
    public function setPasswordAttribute($value)
    {
        $this->attributes['nv_matKhau'] = bcrypt($value);
    }
}