12/08/2018, 13:11

Laravel 5.2 - New Features

Laravel 5.2 đã được phát hành từ ngày, nó có khá nhiều điểm mới so với phiên bản 5.1 như hỗ trợ multiple authentication driver, implicit model binding, simplified Eloquent global scopes, authentication scaffolding, middleware groups, rate limiting middleware, array validation improvements, and ...

laravel-5-2.png

Laravel 5.2 đã được phát hành từ ngày, nó có khá nhiều điểm mới so với phiên bản 5.1 như hỗ trợ multiple authentication driver, implicit model binding, simplified Eloquent global scopes, authentication scaffolding, middleware groups, rate limiting middleware, array validation improvements, and more...

1. Form array validation

Form array validation làm đơn giản hóa quá trình kiểm tra dữ liệu đầu vào từ HTML forms khi sử dụng dữ liệu dạng mảng. Hãy tưởng tượng, bạn có 1 form nơi mà bạn thêm công ty và các nhân viên của công ty đó, mỗi nhân viên có 2 thông tin cơ bản là tên và title. Dưới đây là một form cơ bản để add 1 công ty với 2 nhân viên.

<form>
    <label>Company Name</label>
    <input type="text" name="name">
    <h3>Employees</h3>
    <div class="add-employee">
        <label>Employee Name</label>
        <input type="text" name="employee[1][name]">
        <label>Employee Title</label>
        <input type="text" name="employee[1][title]">
    </div>
    <div class="add-employee">
        <label>Employee Name</label>
        <input type="text" name="employee[2][name]">
        <label>Employee Title</label>
        <input type="text" name="employee[2][title]">
    </div>
    <a href="#" class="js-create-new-add-employee-box">Add another employee</a>
    <input type="submit">
</form>

Để kiểm tra dữ liệu được submit từ form, chúng ta thường dùng:

// CompaniesController.php
$this->validate($request->all(), [
    'name' => 'required|string',
    'employee.1.name' => 'required|string',
    'employee.2.name' => 'required|string',
    'employee.1.title' => 'string',
    'employee.2.title' => 'string',
]);

Nhưng với Laravel 5.2, chúng ta có thể đơn giản hóa và làm ngắn gọn lại phần validate bằng array validation rule

// CompaniesController.php
$this->validate($request->all(), [
    'name' => 'required|string',
    'employee.*.name' => 'required|string',
    'employee.*.title' => 'string',
]);

2. Implicit model binding

Từ Laravel 5.1 trở về trước, chúng ta thường truyền id vào đường link route, và trong controller chúng ta phải tìm phần tử có id tương ứng,....

Route::get('posts/{id}', function ($id) {
    $post = Post::findOrFail($id);
    // ...
});

Tuy nhiên, với Laravel 5.2, chúng ta chỉ cần truyền id vào route, và Laravel sẽ tự động tìm phần tử tương ứng, nó sẽ throw exception khi không tìm thấy phần tử nào tương ứng với idmà chúng ta đã truyền vào.

Route::get('posts/{post}', function (Post $post) {
    // ...
});

3. API rate limiting

  • Giới thiệu về rate limiting

    Đối với những developer làm việc với việc tạo API thì việc giới hạn các request từ client là công việc thường thấy, để làm được điều đó trong laravel, họ thường phải tạo class riêng và thực hiện việc giới hạn request bằng tay. rate limiting được hiểu đơn giản là "số lượng request mà một cá nhân có thể tạo ra". Ví dụ, nếu có 1 cá nhân nào đó (hoặc cũng có thể là bot), gửi hàng nghìn request hoặc hơn trong 1 phút, ứng dụng của bạn sẽ không bị crash bởi vì rate limiting đã hạn chế số lượng request, người đó sẽ nhận được lỗi 429: Too Many Attempts từ server.

  • Sử dụng rate-limiting trong Laravel 5.2

    Trong Laravel 5.2, chúng ta có thể sử dụng throttle middleware cho một group. Ví dụ với 1 API group:

    Route::group(['prefix' => 'api'], function () {
        Route::get('people', function () {
            return Person::all();
        });
    });
Chúng ta đặt `throttle` giới hạn 60 lần trên 1 phút, và chặn truy cập trong 1 phút nếu họ đã đạt mức giới hạn truy cập:
    Route::group(['prefix' => 'api', 'middleware' => 'throttle:60'], function () {
        Route::get('people', function () {
            return Person::all();
        });
    });
Nếu một người nào đó đã đạt tới giới hạn (ví dụ 5 lần trong 1 phút) và chúng ta không muốn cho họ truy cập trong 10 phút
    Route::group(['prefix' => 'api', 'middleware' => 'throttle:5,10'], function () {
        Route::get('people', function () {
            return Person::all();
        });
    });

4. Middleware groups

Khi bạn đang tạo một trang web kích thước đáng kể trong Laravel, file routes của bạn sẽ rất lớn với. Vì vậy bạn sẽ tổ chức lại nó thành các groups riêng biệt. Vấn đề gặp phải là mỗi group sẽ có thể sử dụng middleware khác nhau, hoặc rate limiter khác nhau,...

Laravel 5.2 đã mang tới một giải pháp cho vấn đề trên, middleware groups là một shortcut để áp dụng một nhóm các middlewares bằng một key. Chúng ta có thể định nghĩa middleware group trong appHttpKernel.php. Trong đó có một property mới so với Laravel 5.1 là $middlewareGroups, một array mà mỗi phần tử của nó là một cặp tên - middleware tương ứng.

Ví dụ, admin sử dụng middleware web và auth:

protected $middlewareGroups = [
    'web' => [
        AppHttpMiddlewareEncryptCookies::class,
        IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
        IlluminateSessionMiddlewareStartSession::class,
        IlluminateViewMiddlewareShareErrorsFromSession::class,
        AppHttpMiddlewareVerifyCsrfToken::class,
    ],

    'api' => [
        'throttle:60,1',
    ],

    'admin' => [
        'web',
        'auth',
    ]
];

Và ở trong file routes chúng ta khai sử dụng key admin mà chúng ta đã khai báo trong $middlewareGroups như một middleware

Route::group(['middleware' => 'admin'], function () {
    Route::get('dashboard', function () {
        return view('dashboard');
    });
});

5. The auth scaffold

Hầu như các trang web đều có phần giống nhau cơ bản như đăng kí, login, reset password, home page,... Laravel 5.2 sử dụng một scaffold để tự động tạo ra những thành phần như này. Với command: make:auth, chúng ta sẽ có một file resources/views/layouts/app.blade.php là layout cơ bản của các phần còn lại:

  • welcome.blade.php - trang welcome thường thấy của Laravel
  • home.blade.php - trang home của user sau login
  • auth/login.blade.php - trang login
  • auth/register.blade.php - trang đăng ký
  • auth/passwords/email.blade.php - trang confirm reset password
  • auth/passwords/reset.blade.php - trang request reset password
  • auth/emails/password.blade.php -

Chúng ta có một HomeController:

class HomeController extends Controller
{
    /**
     * Show the application dashboard.
     *
     * @return Response
     */
    public function index()
    {
        return view('home');
    }
}

Đông thời chúng ta có file routes với nội dung tương ứng.

Route::group(['middleware' => 'web'], function () {
    Route::auth();

    Route::get('/home', 'HomeController@index');
});

Route::auth() là shortcut tương ứng với các routes sau:

// Authentication Routes...
$this->get('login', 'AuthAuthController@showLoginForm');
$this->post('login', 'AuthAuthController@login');
$this->get('logout', 'AuthAuthController@logout');

// Registration Routes...
$this->get('register', 'AuthAuthController@showRegistrationForm');
$this->post('register', 'AuthAuthController@register');

// Password Reset Routes...
$this->get('password/reset/{token?}', 'AuthPasswordController@showResetForm');
$this->post('password/email', 'AuthPasswordController@sendResetLinkEmail');
$this->post('password/reset', 'AuthPasswordController@reset');

Không có gì quá phức tạp nhưng nó giúp chúng ta tiết kiệm được khá nhiều thời gian, và không phải viết lại những đoạn code này trên những project khác

6. Multiple authentication

Ngày nay, một trang web thường hỗ trợ nhiều kiểu người dùng, chúng ta có thể sử quản lý các kiểu người dùng này bằng một trường trong cơ sở dữ liệu. Tuy nhiên việc đó không được khuyến khích. Nếu chúng ta sử dụng Laravel 5.1 trở về trước, để hỗ trợ nhiều kiểu người dùng, chúng ta thường phải sử dụng thêm các thư viện ngoài như Kbwebs/MultiAuth,... Vấn đề này đã được giải quyết bởi Laravel 5.2 bởi multiple authentication.

Để sử dụng multiple authentication, đầu tiên chúng ta phải config trong file config/auth.php

<?php

return [
    'defaults' => [
        'guard'     => 'user',
        'passwords' => 'user',
    ],

    'guards' => [
        'admin' => [
            'driver'   => 'session',
            'provider' => 'admin',
        ],
        'user' => [
            'driver'   => 'session',
            'provider' => 'user',
        ],
    ],

    'providers' => [
        'admin' => [
            'driver' => 'eloquent',
            'model'  => AppModelsAdmin::class
        ],
        'user' => [
            'driver' => 'eloquent',
            'model'  => AppModelsUser::class
        ],
    ],

    'passwords' => [
        'admin' => [
            'provider' => 'admin',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
        'user' => [
            'provider' => 'user',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];

Trong controller, ví dụ với Admin

// AppHttpControllersAdminSessionController.php

// Admin login
public function login(Request $credentials)
{
    //...
    Auth::guard('admin')->attempt($credentials, true);
    // ...
}

// Admin logout
public function logout()
{
    // ...
    Auth::guard('admin')->logout();
    // ...
}

public function someFunction()
{
    if (Auth::guard('admin')->check()) {
        $admin = Auth::guard('admin')->user();
        // ...
    }
}

Các hàm cơ bản mà chúng ta hay sử dụng khi sử dụng multiple authentication:

  • Auth::guard('user')->login(credentials,credentials, credentials,remember_me); // Login với thuộc tính $$emember_me
  • Auth::guard('user')->logout(); // Logout user
  • Auth::guard('user')->check(); // Kiểm tra xem user đã login hay chưa
  • Auth::guard('user')->user(); // Lấy thông tin của user
0