TL;DR: On Wednesday, February 7, 2018, Laravel 5.6, was released to the public. It's a major release to the most popular PHP framework on GitHub as of this writing. Furthermore, Spark 6.0 was also released alongside Laravel 5.6. According to the policy laid down by the Taylor and the core team, major Laravel framework releases are released every six months (February and August). In this article, I'll cover the new features in Laravel 5.6 and several other changes and deprecations.
Laravel is the most popular, open-source PHP framework as of this writing. It is designed for building web applications with an expressive and elegant syntax. With Laravel, application development is fast because it ships with a lot of features out of the box. Without further ado, let's dive right into Laravel 5.6.
What's new in Laravel 5.6?
1. Support For Argon Password Hashing
Argon2, the recommended password hashing algorithm by the Password Hashing Competition, is a modern algorithm for securely hashing passwords. And it comes in two distinct flavors, Argon 2i and Argon 2d. PHP 7.2 recently added support for Argon 2i password hashing. Therefore, Michael Lundbol took the initiative to add support for Argon hashing in Laravel.
The bcrypt
driver is the default driver for password hashing in Laravel. However, Laravel 5.6 now supports argon
.
Note: Laravel 5.6 ships with a hashing config file as displayed above.
2. Better Support For Dynamic Rate Limiting
One of the beautiful built-in features of Laravel is API Rate Limiting. Before now, Laravel's rate limiting configuration involved specifying a hard-coded number of requests on a group of routes. However, Laravel 5.6 adds icing to the cake by allowing you specify a maximum number of requests based on an authenticated User model attribute.
Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
Route::get('/users', function () {
// do something awesome
});
});
In the code above, the rate_limit
parameter is an attribute of the User
model in a Laravel 5.6 application.
3. Model Serialization on Steriods
Before now, there was a persistent bug on queued models. When queued models are finally processed, it's without their loaded relationships in place.
In Laravel 5.6, huge improvements have been made to ensure that relationships loaded on queued models are automatically re-loaded when the job is processed by the queue.
4. Improved Logging
There is a new logging config file in Laravel 5.6. In this file, you can set up logging stacks that send log messages to various handlers.
Check out the example below:
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['syslog', 'slack'],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
],
The stack
driver allows you to combine multiple channels, in this case, syslog
and slack
, into a single log channel as shown above.
Furthermore, with the tap
array on a channel's configuration, you can easily customize Monolog for an existing channel like so:
'single' => [
'driver' => 'single',
'tap' => [App\Logging\CustomizeFormatter::class],
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
Note: Monolog is a library that sends your application logs to files, sockets, inboxes, databases and various web services. It's a comprehensive library with various log handlers.
Check out more information on Logging in Laravel 5.6.
5. Single Server Task Scheduling
Before now, if your app ran on multiple servers and the task scheduler was active on those servers, then your scheduled tasks also executed multiple times. However, in Laravel 5.6, you can now schedule your task to execute on just a single server if your app runs on multiple servers.
" In Laravel 5.6, you can now schedule your task to execute on just a single server if your app runs on multiple servers."
Tweet This
$schedule->command('launch:flasheavy')
->tuesdays()
->at('12:00')
->onOneServer();
6. Beautiful Error Reporting With Collision
Collision is an awesome package developed and maintained by Nuno Maduro. It is a detailed, beautiful and intuitive error handler for console/command-line PHP applications.
Laravel 5.6 now ships with Collision via the dev
composer dependency. When working with your Laravel app via the command line, Collision provides an awesome error reporting interface like so:
7. Elevated Eloquent Date Formatting
Laravel 5.6 provides a subtle way to cast Eloquent date model attributes to a specific date format. All you need to do is to specify the desired date format in the $casts
array.
"Laravel 5.6 provides a subtle way to cast Eloquent date model attributes to a specific date format."
Tweet This
Now, you can customize the date model attributes like so:
protected $casts = [
'date_enrolled' => 'date:Y-m-d',
'date_evicted' => 'datetime:Y-m-d H:00',
];
When the model is cast to JSON or array output, the attributes will be formatted to the date formats example provided above like so:
date_enrolled: 2005-02-19
date_evicted: 2018-02-20 8:30
8. Aliasing Blade Components For Easier Access
This feature is very handy. Accessing a blade component in a sub-directory is easier via aliasing. With the component method, you can alias components.card
to card
assuming the card component's directory is resources/views/components/card.blade.php
.
Blade::component('components.card', 'card');
Once it has been aliased, you can invoke the component like so:
@card
This is your Valentine card.
@card
9. Broadcasting Channel Classes
In Laravel 5.6, you can now generate broadcasting channel classes via the make:channel
Artisan command. The generated channel class will be placed in the App/Broadcasting
directory.
php artisan make:channel PurchaseChannel
Registering the channel is as easy as calling the Broadcast::channel
method below in the routes/channel.php
file:
use App\Broadcasting\PurchaseChannel;
Broadcast::channel('purchase.{purchase}', PurchaseChannel::class);
In the PurchaseChannel
class, you can add the authorization logic in the join
method. Before now, the authorization logic was placed in the channel authorization Closure.
<?php
namespace App\Broadcasting;
use App\User;
use App\Purchase;
class PurchaseChannel
{
....
/**
* Authenticate the user's access to the channel.
*
* @param \App\User $user
* @param \App\Purchase $purchase
* @return array|bool
*/
public function join(User $user, Purchase $purchase)
{
return $user->id === $purchase->user_id;
}
}
10. Daring Upgrade Of Symfony Components and Bootstrap
All the Symfony components used by Laravel 5.6 have been bumped to the ~4.0
release. Furthermore, all the front-end scaffolding of Laravel 5.6 and Spark 6.0 has been bumped to v4
.
I covered all the major additions and deprecations of Bootstrap 4 in this article.
Deprecations and Other Updates
- Generating an API resource controller can now be done by using the
--api
switch when executing themake:controller
command. - Laravel 5.6 introduced helper methods,
Arr::wrap()
,classes_uses_recursive()
,Str::uuid()
, andStr::orderedUuid()
, the latter generating a timestamp first UUID that's more easily and efficiently indexed by databases like MySQL. - PHPUnit, upgraded to v7.
- Laravel Mix, upgraded to v2.
- The deprecated Artisan
optimize
command has been removed. - Added support for customizing the mail message building in
ResetPassword::toMail()
. - Add
policies()
method toAuthServiceProvider
to retrieve all the policies defined by the provider. - Two new blade directives have been added to the framework,
@csrf
and@method
. - Support for PostgreSQL comments was added. Furthermore, Laravel 5.6 now has better support for enumeration columns.
Check out other Laravel 5.6 updates here.
Upgrading to Laravel 5.6
Laravel 5.6 requires PHP >= 7.1.3
. And the estimated upgrade time from Laravel v5.5
is about ten to thirty minutes.
Check out this comprehensive upgrade guide. However, if you don't want to be bothered about manually configuring and changing files for the upgrade, I recommend using Laravel Shift - A service that provides automated, instant Laravel upgrade services by an army of thorough bots and friendly humans.
Aside: Securing Laravel APIs with Auth0
Securing Laravel APIs with Auth0 is very easy and brings a lot of great features to the table. With Auth0, you only have to write a few lines of code to get:
- A solid identity management solution, including single sign-on
- User management
- Support for social identity providers (like Facebook, GitHub, Twitter, etc.)
- Enterprise identity providers (Active Directory, LDAP, SAML, etc.)
- Our own database of users
Sign Up for Auth0
You'll need an Auth0 account to manage authentication. You can sign up for a free account here. Next, set up an Auth0 API.
Set Up an API
Go to APIs in your Auth0 dashboard and click on the "Create API" button. Enter a name for the API. Set the Identifier to a URL(existent or non-existent URL). The Signing Algorithm should be RS256
.
You're now ready to implement Auth0 authentication in your Laravel API.
Dependencies and Setup
Install the laravel-auth0
package by entering the following in your terminal:
composer require auth0/login:"~5.0"
Generate the laravel-auth0
package config file:
php artisan vendor:publish
After the file is generated, it will be located at config/laravel-auth0.php
. Double check your values match those found here.
Now you need to open your .env
file to create and fill in those variables. Add the following anywhere in your .env
file:
AUTH0_DOMAIN=kabiyesi.auth0.com
AUTH0_CLIENT_ID=xxxxxxxxxxxxxxxxxx
AUTH0_CLIENT_SECRET=xxxxxxxxxxxxxxxxx
AUTH0_AUDIENCE=http://mylaravelapi.com
AUTH0_CALLBACK_URL=null
Now replace all of those placeholders with the corresponding value from your Auth0 dashboard.
Activate Provider and Facade
The laravel-auth0
package comes with a provider called LoginServiceProvider
. Add this to the list of application providers:
// config/app.php
'providers' => array(
// ...
\Auth0\Login\LoginServiceProvider::class,
);
If you would like to use the Auth0
Facade, add it to the list of aliases
.
// config/app.php
'aliases' => array(
// ...
'Auth0' => \Auth0\Login\Facade\Auth0::class,
);
The user information can now be accessed with Auth0::getUser()
. Finally, you need to bind a class that provides a user (your app model user) each time the user is logged in or an access_token
is decoded. You can use the Auth0UserRepository
provided by this package or you can build your own class.
To use Auth0UserRepository
, add the following lines to your app's AppServiceProvider
:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->bind(
\Auth0\Login\Contract\Auth0UserRepository::class,
\Auth0\Login\Repository\Auth0UserRepository::class
);
}
Configure Authentication Driver
The laravel-auth0
package comes with an authentication driver called auth0
. This driver defines a user structure that wraps the normalized user profile defined by Auth0. It doesn't persist the object but rather simply stores it in the session for future calls.
This is adequate for basic testing or if you don't need to persist the user. At any point you can call Auth::check()
to determine if there is a user logged in and Auth::user()
to retrieve the wrapper with the user information.
Configure the driver in config/auth.php
to use auth0
.
// app/config/auth.php
// ...
'providers' => [
'users' => [
'driver' => 'auth0'
],
],
Secure API Routes
Your API routes are defined in routes/api.php
for Laravel 5.3+ apps.
// routes/api.php
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('/public', function (Request $request) {
return response()->json(["message" => "Hello from a public endpoint! You don't need any token to access this URL..Yaaaay!"]);
});
Route::get('/wakanda', function (Request $request) {
return response()->json(["message" => "Access token is valid. Welcome to this private endpoint. You need elevated scopes to access Vibranium."]);
})->middleware('auth:api');
Now you can send a request to your protected endpoint with an access_token
:
curl --request GET \
--url http://localhost:8000/api/wakanda \
--header 'authorization: Bearer <ACCESS TOKEN>'
Once a user hits the api/wakanda
endpoint, a valid JWT access_token
will be required before the resource can be released. With this in place, private routes can be secured.
More Resources
That's it! You have an authenticated Laravel API with protected routes. To learn more, check out the following resources:
Conclusion
Laravel 5.6 came loaded with new features and significant improvements. Another major release will be out by August and some of the features shipping with the next major release will be unleashed at Laracon 2018. Get your tickets already!
Have you upgraded to Laravel v5.6 yet? What are your thoughts? Let me know in the comments section! 😊