laravel5.7 Eloquentの$fillableとは

Modelの中で記載する$fillableとは?

class Account extends Model
{
    //
    protected $table = 'account';
    protected $fillable = [
    	'login',
    	'foo',
    	'hoge',
    ];
}

公式Eloquentのページを見てみます。
https://readouble.com/laravel/5.7/ja/eloquent.html

以下の記載があります。
—-
一行だけで新しいモデルを保存するには、createメソッドが利用できます。挿入されたモデルインスタンスが、メソッドから返されます。しかし、これを利用する前に、Eloquentモデルはデフォルトで複数代入から保護されているため、モデルへfillableかguarded属性のどちらかを設定する必要があります。

複数代入の脆弱性はリクエストを通じて予期しないHTTPパラメーターが送られた時に起き、そのパラメーターはデータベースのカラムを予期しないように変更してしまうでしょう。たとえば悪意のあるユーザーがHTTPパラメーターでis_adminパラメーターを送り、それがモデルのcreateメソッドに対して渡されると、そのユーザーは自分自身を管理者(administrator)に昇格できるのです。

ですから最初に複数代入したいモデルの属性を指定してください。モデルの$fillableプロパティで指定できます。たとえば、Flightモデルの複数代入でname属性のみ使いたい場合です。
—-
う~ 日本語がなんか滅茶苦茶だ。すっと頭に入ってこないぞ、と思ったが、よく読むと、HTTPリクエストのパラメーターがカラムを変更してしまうから、予めモデルの属性をfillableかguardedで設定すると書いてある。

なるほど、納得!!!

Laravel5.7のmigration(マイグレーション)

migrationとは
マイグレーションとはデータベースのversionコントロール
データベースのスキーマ更新を簡単に出来るようになる


Laravel5.7の公式ドキュメント:
https://readouble.com/laravel/5.7/ja/migrations.html

1. migrationファイルの作成
table名の後ろに”_table”をつけてmigrationファイルを作成します。

php artisan make:migration ${tabale name}_table

では試しにコマンドラインでmigrationファイルを作成しましょう。
[vagrant@localhost zeus]$ php artisan make:migration users_table

/database/migrations 配下に yyyy_mm_dd_hhmmss_users_table.phpが作られます。

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class UsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        //
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        //
    }
}

function upとdownにカラムを書いていきます。

2. migrateの実行

php artisan migrate

databaseにtableが出来ます。ただし、 public function up()が空の場合はなにもできません。

オプションでtable名を指定した場合
[vagrant@localhost zeus]$ php artisan make:migration create_users_tables –create=users
Created Migration: 2018_11_17_154656_create_users_tables
[vagrant@localhost zeus]$ php artisan migrate
Migration table created successfully.
Migrating: 2018_11_17_154656_create_users_tables
Migrated: 2018_11_17_154656_create_users_tables

mysql側
usersのテーブルが出来ているのがわかります。

Laravel 5.7からMySQL 5.6への接続方法

LaravelからMySQLへの接続方法は、
1. MySQLで接続するDBを作成する
2. .envファイルから接続するmysqlのDB Nameなどを指定する です。

1. MySQLで接続するDBを作成する
まずMySQLにログインします。
[vagrant@localhost ~]$ mysql -u root -p

続いて、dbを作成します。既に使用するデータベースがある場合は省略して構わないでしょう。
mysql> create database zeus;

これで、db側の設定は完了です。きちんと作成できたか、show databases;で確認しておくと良いでしょう。

2. .envファイルから接続するmysqlのDB Nameなどを指定する
.envファイルは、laravelをインストールしたディレクトリにあります。この.envを開きます。

.envは設定ファイルで、アプリ(APP_*)、DB(DB_*)、Redis(REDIS_*)、メール(MAIL_*)、Pusher(PUSHER_*)などの設定が書かれています。今回編集するのは
9~14行目のDBの箇所です。

DB_CONNECTION、DB_HOST、DB_PORTはlocalの場合は変更の必要ありません。RDSにつないでいる時などは設定しましょう。主に編集するのは、DB_DATABASE、DB_USERNAME、DB_PASSWORDの箇所です。適時変更ください。

DB_DATABASE=zeus
DB_USERNAME=root
DB_PASSWORD=

これでLaravelの接続設定は完了です。

laravelのバージョン確認方法

Laravelのバージョン確認方法は、
1. Laravelがインストールされているディレクトリに行く
2. コマンドラインでphp artisan -Vと打つ

1. Laravelがインストールされているディレクトリに行く
laravelのバージョン確認は、artisanコマンドを使います。その為、laravelがインストールされていないディレクトリではartisanコマンドは使えず、バージョン確認ができません。

2. コマンドラインで php artisan -V と打つ

[vagrant@localhost zeus]$ php artisan -V
Laravel Framework 5.7.11

php artisan –versionでも大丈夫です。

[vagrant@localhost zeus]$ php artisan --version
Laravel Framework 5.7.11

公式ドキュメントでは –version が紹介されています。
https://readouble.com/laravel/5.dev/ja/artisan.html

プログラマーとしては php artisan -V の方がいいでしょうね。

auth.php Language file

Introduction
This is not original Laravel official documentaion. This page include into readouble.com to show original English content of Japanese translation.

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used during authentication for various
    | messages that we need to display to the user. You are free to modify
    | these language lines according to your application's requirements.
    |
    */

    'failed' => 'These credentials do not match our records.',
    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',

];

return [

    /*
    |--------------------------------------------------------------------------
    | Pagination Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used by the paginator library to build
    | the simple pagination links. You are free to change them to anything
    | you want to customize your views to better match your application.
    |
    */

    'previous' => '« Previous',
    'next' => 'Next »',

 'password' => 'Passwords must be at least six characters and match the confirmation.',
    'reset' => 'Your password has been reset!',
    'sent' => 'We have e-mailed your password reset link!',
    'token' => 'This password reset token is invalid.',
    'user' => "We can't find a user with that e-mail address.",
 'accepted'             => 'The :attribute must be accepted.',
    'active_url'           => 'The :attribute is not a valid URL.',
    'after'                => 'The :attribute must be a date after :date.',
    'after_or_equal'       => 'The :attribute must be a date after or equal to :date.',
    'alpha'                => 'The :attribute may only contain letters.',
    'alpha_dash'           => 'The :attribute may only contain letters, numbers, and dashes.',
    'alpha_num'            => 'The :attribute may only contain letters and numbers.',
    'array'                => 'The :attribute must be an array.',
    'before'               => 'The :attribute must be a date before :date.',
    'before_or_equal'      => 'The :attribute must be a date before or equal to :date.',
    'between'              => [
        'numeric' => 'The :attribute must be between :min and :max.',
        'file'    => 'The :attribute must be between :min and :max kilobytes.',
        'string'  => 'The :attribute must be between :min and :max characters.',
        'array'   => 'The :attribute must have between :min and :max items.',
    ],
    'boolean'              => 'The :attribute field must be true or false.',
    'confirmed'            => 'The :attribute confirmation does not match.',
    'date'                 => 'The :attribute is not a valid date.',
    'date_format'          => 'The :attribute does not match the format :format.',
    'different'            => 'The :attribute and :other must be different.',
    'digits'               => 'The :attribute must be :digits digits.',
    'digits_between'       => 'The :attribute must be between :min and :max digits.',
    'dimensions'           => 'The :attribute has invalid image dimensions.',
    'distinct'             => 'The :attribute field has a duplicate value.',
    'email'                => 'The :attribute must be a valid email address.',
    'exists'               => 'The selected :attribute is invalid.',
    'file'                 => 'The :attribute must be a file.',
    'filled'               => 'The :attribute field must have a value.',
    'image'                => 'The :attribute must be an image.',
    'in'                   => 'The selected :attribute is invalid.',
    'in_array'             => 'The :attribute field does not exist in :other.',
    'integer'              => 'The :attribute must be an integer.',
    'ip'                   => 'The :attribute must be a valid IP address.',
    'ipv4'                 => 'The :attribute must be a valid IPv4 address.',
    'ipv6'                 => 'The :attribute must be a valid IPv6 address.',
    'json'                 => 'The :attribute must be a valid JSON string.',
    'max'                  => [
        'numeric' => 'The :attribute may not be greater than :max.',
        'file'    => 'The :attribute may not be greater than :max kilobytes.',
        'string'  => 'The :attribute may not be greater than :max characters.',
        'array'   => 'The :attribute may not have more than :max items.',
    ],
    'mimes'                => 'The :attribute must be a file of type: :values.',
    'mimetypes'            => 'The :attribute must be a file of type: :values.',
    'min'                  => [
        'numeric' => 'The :attribute must be at least :min.',
        'file'    => 'The :attribute must be at least :min kilobytes.',
        'string'  => 'The :attribute must be at least :min characters.',
        'array'   => 'The :attribute must have at least :min items.',
    ],
    'not_in'               => 'The selected :attribute is invalid.',
    'numeric'              => 'The :attribute must be a number.',
    'present'              => 'The :attribute field must be present.',
    'regex'                => 'The :attribute format is invalid.',
    'required'             => 'The :attribute field is required.',
    'required_if'          => 'The :attribute field is required when :other is :value.',
    'required_unless'      => 'The :attribute field is required unless :other is in :values.',
    'required_with'        => 'The :attribute field is required when :values is present.',
    'required_with_all'    => 'The :attribute field is required when :values is present.',
    'required_without'     => 'The :attribute field is required when :values is not present.',
    'required_without_all' => 'The :attribute field is required when none of :values are present.',
    'same'                 => 'The :attribute and :other must match.',
    'size'                 => [
        'numeric' => 'The :attribute must be :size.',
        'file'    => 'The :attribute must be :size kilobytes.',
        'string'  => 'The :attribute must be :size characters.',
        'array'   => 'The :attribute must contain :size items.',
    ],
    'string'               => 'The :attribute must be a string.',
    'timezone'             => 'The :attribute must be a valid zone.',
    'unique'               => 'The :attribute has already been taken.',
    'uploaded'             => 'The :attribute failed to upload.',
    'url'                  => 'The :attribute format is invalid.',

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | Here you may specify custom validation messages for attributes using the
    | convention "attribute.rule" to name the lines. This makes it quick to
    | specify a specific custom language line for a given attribute rule.
    |
    */

    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Attributes
    |--------------------------------------------------------------------------
    |
    | The following language lines are used to swap attribute place-holders
    | with something more reader friendly such as E-Mail Address instead
    | of "email". This simply helps us make messages a little cleaner.
    |
    */

    'attributes' => [],


];

やっと終わったー

Laravel Socialite

In addition to typical, form based authentication, Laravel also provides a simple, convenient way to authenticate with OAuth providers using Laravel Socialite. Socialite currently supports authentication with Facebook, Twitter, LinkedIn, Google, GitHub and Bitbucket.

Tip!! Adapters for other platforms are listed at the community driven Socialite Providers website.

Installation
To get started with Socialite, use Composer to add the package to your project’s dependencies:

composer require laravel/socialite

Configuration
Before using Socialite, you will also need to add credentials for the OAuth services your application utilizes. These credentials should be placed in your config/services.php configuration file, and should use the key facebook, twitter, linkedin, google, github or bitbucket, depending on the providers your application requires. For example:

‘github’ => [
‘client_id’ => env(‘GITHUB_CLIENT_ID’), // Your GitHub Client ID
‘client_secret’ => env(‘GITHUB_CLIENT_SECRET’), // Your GitHub Client Secret
‘redirect’ => ‘http://your-callback-url’,
],

Routing
Next, you are ready to authenticate users! You will need two routes: one for redirecting the user to the OAuth provider, and another for receiving the callback from the provider after authentication. We will access Socialite using the Socialite facade:

redirect();
}

/**
* Obtain the user information from GitHub.
*
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback()
{
$user = Socialite::driver(‘github’)->user();

// $user->token;
}
}
The redirect method takes care of sending the user to the OAuth provider, while the user method will read the incoming request and retrieve the user’s information from the provider.

Of course, you will need to define routes to your controller methods:

Route::get(‘login/github’, ‘Auth\LoginController@redirectToProvider’);
Route::get(‘login/github/callback’, ‘Auth\LoginController@handleProviderCallback’);

Optional Parameters
A number of OAuth providers support optional parameters in the redirect request. To include any optional parameters in the request, call the with method with an associative array:

return Socialite::driver(‘google’)
->with([‘hd’ => ‘example.com’])
->redirect();
Note: When using the with method, be careful not to pass any reserved keywords such as state or response_type.

Access Scopes
Before redirecting the user, you may also add additional “scopes” on the request using the scopes method. This method will merge all existing scopes with the ones you supply:

return Socialite::driver(‘github’)
->scopes([‘read:user’, ‘public_repo’])
->redirect();
You can overwrite all existing scopes using the setScopes method:

return Socialite::driver(‘github’)
->setScopes([‘read:user’, ‘public_repo’])
->redirect();
Stateless Authentication
The stateless method may be used to disable session state verification. This is useful when adding social authentication to an API:

return Socialite::driver(‘google’)->stateless()->user();
Retrieving User Details
Once you have a user instance, you can grab a few more details about the user:

$user = Socialite::driver(‘github’)->user();

// OAuth Two Providers
$token = $user->token;
$refreshToken = $user->refreshToken; // not always provided
$expiresIn = $user->expiresIn;

// OAuth One Providers
$token = $user->token;
$tokenSecret = $user->tokenSecret;

// All Providers
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
Retrieving User Details From A Token (OAuth2)
If you already have a valid access token for a user, you can retrieve their details using the userFromToken method:

$user = Socialite::driver(‘github’)->userFromToken($token);
Retrieving User Details From A Token And Secret (OAuth1)
If you already have a valid pair of token / secret for a user, you can retrieve their details using the userFromTokenAndSecret method:

$user = Socialite::driver(‘twitter’)->userFromTokenAndSecret($token, $secret);

Laravel Scout

Introduction
Laravel Scout provides a simple, driver based solution for adding full-text search to your Eloquent models. Using model observers, Scout will automatically keep your search indexes in sync with your Eloquent records.

Currently, Scout ships with an Algolia driver; however, writing custom drivers is simple and you are free to extend Scout with your own search implementations.

Installation
First, install Scout via the Composer package manager:

composer require laravel/scout
After installing Scout, you should publish the Scout configuration using the vendor:publish Artisan command. This command will publish the scout.php configuration file to your config directory:

php artisan vendor:publish –provider=”Laravel\Scout\ScoutServiceProvider”

Finally, add the Laravel\Scout\Searchable trait to the model you would like to make searchable. This trait will register a model observer to keep the model in sync with your search driver:

namespace App;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
use Searchable;
}

Queueing
While not strictly required to use Scout, you should strongly consider configuring a queue driver before using the library. Running a queue worker will allow Scout to queue all operations that sync your model information to your search indexes, providing much better response times for your application’s web interface.

Once you have configured a queue driver, set the value of the queue option in your config/scout.php configuration file to true:

Driver Prerequisites
Algolia
When using the Algolia driver, you should configure your Algolia id and secret credentials in your config/scout.php configuration file. Once your credentials have been configured, you will also need to install the Algolia PHP SDK via the Composer package manager:

composer require algolia/algoliasearch-client-php

Configuring Model Indexes
Each Eloquent model is synced with a given search “index”, which contains all of the searchable records for that model. In other words, you can think of each index like a MySQL table. By default, each model will be persisted to an index matching the model’s typical “table” name. Typically, this is the plural form of the model name; however, you are free to customize the model’s index by overriding the searchableAs method on the model:

namespace App;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use Searchable;

    /**
     * Get the index name for the model.
     *
     * @return string
     */
    public function searchableAs()
    {
        return 'posts_index';
    }
}

Indexing
Batch Import
If you are installing Scout into an existing project, you may already have database records you need to import into your search driver. Scout provides an import Artisan command that you may use to import all of your existing records into your search indexes:

php artisan scout:import “App\Post”
The flush command may be used to remove all of a model’s records from your search indexes:

php artisan scout:flush “App\Post”
Adding Records
Once you have added the Laravel\Scout\Searchable trait to a model, all you need to do is save a model instance and it will automatically be added to your search index. If you have configured Scout to use queues this operation will be performed in the background by your queue worker:

$order = new App\Order;

// …

$order->save();
Adding Via Query
If you would like to add a collection of models to your search index via an Eloquent query, you may chain the searchable method onto an Eloquent query. The searchable method will chunk the results of the query and add the records to your search index. Again, if you have configured Scout to use queues, all of the chunks will be added in the background by your queue workers:

// Adding via Eloquent query…
App\Order::where(‘price’, ‘>’, 100)->searchable();

// You may also add records via relationships…
$user->orders()->searchable();

// You may also add records via collections…
$orders->searchable();
The searchable method can be considered an “upsert” operation. In other words, if the model record is already in your index, it will be updated. If it does not exist in the search index, it will be added to the index.

Updating Records
To update a searchable model, you only need to update the model instance’s properties and save the model to your database. Scout will automatically persist the changes to your search index:

$order = App\Order::find(1);

// Update the order…

$order->save();
You may also use the searchable method on an Eloquent query to update a collection of models. If the models do not exist in your search index, they will be created:

// Updating via Eloquent query…
App\Order::where(‘price’, ‘>’, 100)->searchable();

// You may also update via relationships…
$user->orders()->searchable();

// You may also update via collections…
$orders->searchable();
Removing Records
To remove a record from your index, delete the model from the database. This form of removal is even compatible with soft deleted models:

$order = App\Order::find(1);

$order->delete();
If you do not want to retrieve the model before deleting the record, you may use the unsearchable method on an Eloquent query instance or collection:

// Removing via Eloquent query…
App\Order::where(‘price’, ‘>’, 100)->unsearchable();

// You may also remove via relationships…
$user->orders()->unsearchable();

// You may also remove via collections…
$orders->unsearchable();
Pausing Indexing
Sometimes you may need to perform a batch of Eloquent operations on a model without syncing the model data to your search index. You may do this using the withoutSyncingToSearch method. This method accepts a single callback which will be immediately executed. Any model operations that occur within the callback will not be synced to the model’s index:

App\Order::withoutSyncingToSearch(function () {
// Perform model actions…
});
Conditionally Searchable Model Instances
Sometimes you may need to only make a model searchable under certain conditions. For example, imagine you have App\Post model that may be in one of two states: “draft” and “published”. You may only want to allow “published” posts to be searchable. To accomplish this, you may define a shouldBeSearchable method on your model:

public function shouldBeSearchable()
{
return $this->isPublished();
}
Searching
You may begin searching a model using the search method. The search method accepts a single string that will be used to search your models. You should then chain the get method onto the search query to retrieve the Eloquent models that match the given search query:

$orders = App\Order::search(‘Star Trek’)->get();
Since Scout searches return a collection of Eloquent models, you may even return the results directly from a route or controller and they will automatically be converted to JSON:

use Illuminate\Http\Request;

Route::get(‘/search’, function (Request $request) {
return App\Order::search($request->search)->get();
});
If you would like to get the raw results before they are converted to Eloquent models, you should use the raw method:

$orders = App\Order::search(‘Star Trek’)->raw();
Search queries will typically be performed on the index specified by the model’s searchableAs method. However, you may use the within method to specify a custom index that should be searched instead:

$orders = App\Order::search(‘Star Trek’)
->within(‘tv_shows_popularity_desc’)
->get();
Where Clauses
Scout allows you to add simple “where” clauses to your search queries. Currently, these clauses only support basic numeric equality checks, and are primarily useful for scoping search queries by a tenant ID. Since a search index is not a relational database, more advanced “where” clauses are not currently supported:

$orders = App\Order::search(‘Star Trek’)->where(‘user_id’, 1)->get();
Pagination
In addition to retrieving a collection of models, you may paginate your search results using the paginate method. This method will return a Paginator instance just as if you had paginated a traditional Eloquent query:

$orders = App\Order::search(‘Star Trek’)->paginate();
You may specify how many models to retrieve per page by passing the amount as the first argument to the paginate method:

$orders = App\Order::search(‘Star Trek’)->paginate(15);
Once you have retrieved the results, you may display the results and render the page links using Blade just as if you had paginated a traditional Eloquent query:

@foreach ($orders as $order)
{{ $order->price }}
@endforeach

{{ $orders->links() }}
Soft Deleting
If your indexed models are soft deleting and you need to search your soft deleted models, set the soft_delete option of the config/scout.php configuration file to true:

‘soft_delete’ => true,
When this configuration option is true, Scout will not remove soft deleted models from the search index. Instead, it will set a hidden __soft_deleted attribute on the indexed record. Then, you may use the withTrashed or onlyTrashed methods to retrieve the soft deleted records when searching:

// Include trashed records when retrieving results…
$orders = App\Order::withTrashed()->search(‘Star Trek’)->get();

// Only include trashed records when retrieving results…
$orders = App\Order::onlyTrashed()->search(‘Star Trek’)->get();
Tip!! When a soft deleted model is permanently deleted using forceDelete, Scout will remove it from the search index automatically.

Customizing Engine Searches
If you need to customize the search behavior of an engine you may pass a callback as the second argument to the search method. For example, you could use this callback to add geo-location data to your search options before the search query is passed to Algolia:

use AlgoliaSearch\Index;

App\Order::search(‘Star Trek’, function (Index $algolia, string $query, array $options) {
$options[‘body’][‘query’][‘bool’][‘filter’][‘geo_distance’] = [
‘distance’ => ‘1000km’,
‘location’ => [‘lat’ => 36, ‘lon’ => 111],
];

return $algolia->search($query, $options);
})->get();
Custom Engines
Writing The Engine
If one of the built-in Scout search engines doesn’t fit your needs, you may write your own custom engine and register it with Scout. Your engine should extend the Laravel\Scout\Engines\Engine abstract class. This abstract class contains seven methods your custom engine must implement:

use Laravel\Scout\Builder;

abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function mapIds($results);
abstract public function map($results, $model);
abstract public function getTotalCount($results);
You may find it helpful to review the implementations of these methods on the Laravel\Scout\Engines\AlgoliaEngine class. This class will provide you with a good starting point for learning how to implement each of these methods in your own engine.

Registering The Engine
Once you have written your custom engine, you may register it with Scout using the extend method of the Scout engine manager. You should call the extend method from the boot method of your AppServiceProvider or any other service provider used by your application. For example, if you have written a MySqlSearchEngine, you may register it like so:

use Laravel\Scout\EngineManager;

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
resolve(EngineManager::class)->extend(‘mysql’, function () {
return new MySqlSearchEngine;
});
}
Once your engine has been registered, you may specify it as your default Scout driver in your config/scout.php configuration file:

‘driver’ => ‘mysql’,
Builder Macros
If you would like to define a custom builder method, you may use the macro method on the Laravel\Scout\Builder class. Typically, “macros” should be defined within a service provider’s boot method:

engine->getTotalCount(
$this->engine()->search($this)
);
});
}
}
The macro function accepts a name as its first argument, and a Closure as its second. The macro’s Closure will be executed when calling the macro name from a Laravel\Scout\Builder implementation:

App\Order::search(‘Star Trek’)->count();

API Authentication (Passport)

Introduction
Laravel already makes it easy to perform authentication via traditional login forms, but what about APIs? APIs typically use tokens to authenticate users and do not maintain session state between requests. Laravel makes API authentication a breeze using Laravel Passport, which provides a full OAuth2 server implementation for your Laravel application in a matter of minutes. Passport is built on top of the League OAuth2 server that is maintained by Andy Millington and Simon Hamp.

Installation
To get started, install Passport via the Composer package manager:

The Passport service provider registers its own database migration directory with the framework, so you should migrate your database after installing the package. The Passport migrations will create the tables your application needs to store clients and access tokens:

php artisan migrate

Next, you should run the passport:install command. This command will create the encryption keys needed to generate secure access tokens. In addition, the command will create “personal access” and “password grant” clients which will be used to generate access tokens:

php artisan passport:install
After running this command, add the Laravel\Passport\HasApiTokens trait to your App\User model. This trait will provide a few helper methods to your model which allow you to inspect the authenticated user’s token and scopes:

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

Next, you should call the Passport::routes method within the boot method of your AuthServiceProvider. This method will register the routes necessary to issue access tokens and revoke access tokens, clients, and personal access tokens:

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

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();

        Passport::routes();
    }
}
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

Passport ships with a JSON API that you may use to allow your users to create clients and personal access tokens. However, it can be time consuming to code a frontend to interact with these APIs. So, Passport also includes pre-built Vue components you may use as an example implementation or starting point for your own implementation.

To publish the Passport Vue components, use the vendor:publish Artisan command:

php artisan vendor:publish –tag=passport-components

The published components will be placed in your resources/js/components directory. Once the components have been published, you should register them in your resources/js/app.js file:

Vue.component(
    'passport-clients',
    require('./components/passport/Clients.vue')
);

Vue.component(
    'passport-authorized-clients',
    require('./components/passport/AuthorizedClients.vue')
);

Vue.component(
    'passport-personal-access-tokens',
    require('./components/passport/PersonalAccessTokens.vue')
);
After registering the com

After registering the components, make sure to run npm run dev to recompile your assets. Once you have recompiled your assets, you may drop the components into one of your application’s templates to get started creating clients and personal access tokens:

Configuration
Token Lifetimes
By default, Passport issues long-lived access tokens that expire after one year. If you would like to configure a longer / shorter token lifetime, you may use the tokensExpireIn and refreshTokensExpireIn methods. These methods should be called from the boot method of your AuthServiceProvider:
public function boot()
{
$this->registerPolicies();

Passport::routes();

Passport::tokensExpireIn(now()->addDays(15));

Passport::refreshTokensExpireIn(now()->addDays(30));
}

Overriding Default Models
You are free to extend the models used internally by Passport. Then, you may instruct Passport to use your custom models via the Passport class:

use App\Models\Passport\Client;
use App\Models\Passport\AuthCode;
use App\Models\Passport\TokenModel;
use App\Models\Passport\PersonalAccessClient;

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

Passport::routes();

Passport::useClientModel(Client::class);
Passport::useTokenModel(TokenModel::class);
Passport::useAuthCodeModel(AuthCode::class);
Passport::usePersonalAccessClientModel(PersonalAccessClient::class);
}

Issuing Access Tokens
Using OAuth2 with authorization codes is how most developers are familiar with OAuth2. When using authorization codes, a client application will redirect a user to your server where they will either approve or deny the request to issue an access token to the client.

Managing Clients
First, developers building applications that need to interact with your application’s API will need to register their application with yours by creating a “client”. Typically, this consists of providing the name of their application and a URL that your application can redirect to after users approve their request for authorization.

The passport:client Command
The simplest way to create a client is using the passport:client Artisan command. This command may be used to create your own clients for testing your OAuth2 functionality. When you run the client command, Passport will prompt you for more information about your client and will provide you with a client ID and secret:

php artisan passport:client
Redirect URLs

If you would like to whitelist multiple redirect URLs for your client, you may specify them using a comma-delimited list when prompted for the URL by the passport:client command:

JSON API
Since your users will not be able to utilize the client command, Passport provides a JSON API that you may use to create clients. This saves you the trouble of having to manually code controllers for creating, updating, and deleting clients.

However, you will need to pair Passport’s JSON API with your own frontend to provide a dashboard for your users to manage their clients. Below, we’ll review all of the API endpoints for managing clients. For convenience, we’ll use Axios to demonstrate making HTTP requests to the endpoints.

The JSON API is guarded by the web and auth middlewares; therefore, it may only be called from your own application. It is not able to be called from an external source.

Laravel Horizon

Introduction
Horizon provides a beautiful dashboard and code-driven configuration for your Laravel powered Redis queues. Horizon allows you to easily monitor key metrics of your queue system such as job throughput, runtime, and job failures.

All of your worker configuration is stored in a single, simple configuration file, allowing your configuration to stay in source control where your entire team can collaborate.

Installation
Note: Due to its usage of async process signals, Horizon requires PHP 7.1+. Secondly, you should ensure that your queue driver is set to redis in your queue configuration file.

You may use Composer to install Horizon into your Laravel project:
composer require laravel/horizon

After installing Horizon, publish its assets using the vendor:publish Artisan command:
php artisan vendor:publish –provider=”Laravel\Horizon\HorizonServiceProvider”

Configuration
After publishing Horizon’s assets, its primary configuration file will be located at config/horizon.php. This configuration file allows you to configure your worker options and each configuration option includes a description of its purpose, so be sure to thoroughly explore this file.

Balance Options
Horizon allows you to choose from three balancing strategies: simple, auto, and false. The simple strategy, which is the default, splits incoming jobs evenly between processes:

‘balance’ => ‘simple’,

The auto strategy adjusts the number of worker processes per queue based on the current workload of the queue. For example, if your notifications queue has 1,000 waiting jobs while your render queue is empty, Horizon will allocate more workers to your notifications queue until it is empty. When the balance option is set to false, the default Laravel behavior will be used, which processes queues in the order they are listed in your configuration.

Job Trimming
The horizon configuration file allows you to configure how long recent and failed jobs should be persisted (in minutes). By default, recent jobs are kept for one hour while failed jobs are kept for a week:

‘trim’ => [
‘recent’ => 60,
‘failed’ => 10080,
],

Dashboard Authentication
Horizon exposes a dashboard at /horizon. By default, you will only be able to access this dashboard in the local environment. To define a more specific access policy for the dashboard, you should use the Horizon::auth method. The auth method accepts a callback which should return true or false, indicating whether the user should have access to the Horizon dashboard. Typically, you should call Horizon::auth in the boot method of your AppServiceProvider:

Horizon::auth(function ($request) {
    // return true / false;
});

Running Horizon
Once you have configured your workers in the config/horizon.php configuration file, you may start Horizon using the horizon Artisan command. This single command will start all of your configured workers:

php artisan horizon

You may pause the Horizon process and instruct it to continue processing jobs using the horizon:pause and horizon:continue Artisan commands:

php artisan horizon:pause

php artisan horizon:continue
You may gracefully terminate the master Horizon process on your machine using the horizon:terminate Artisan command. Any jobs that Horizon is currently processing will be completed and then Horizon will exit:

php artisan horizon:terminate

Tags
Horizon allows you to assign “tags” to jobs, including mailables, event broadcasts, notifications, and queued event listeners. In fact, Horizon will intelligently and automatically tag most jobs depending on the Eloquent models that are attached to the job. For example, take a look at the following job:

video = $video;
}

/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
If this job is queued with an App\Video instance that has an id of 1, it will automatically receive the tag App\Video:1. This is because Horizon will examine the job’s properties for any Eloquent models. If Eloquent models are found, Horizon will intelligently tag the job using the model’s class name and primary key:

$video = App\Video::find(1);

App\Jobs\RenderVideo::dispatch($video);
Manually Tagging
If you would like to manually define the tags for one of your queueable objects, you may define a tags method on the class:

class RenderVideo implements ShouldQueue
{
/**
* Get the tags that should be assigned to the job.
*
* @return array
*/
public function tags()
{
return [‘render’, ‘video:’.$this->video->id];
}
}
Notifications
Note: Before using notifications, you should add the guzzlehttp/guzzle Composer package to your project. When configuring Horizon to send SMS notifications, you should also review the prerequisites for the Nexmo notification driver.

If you would like to be notified when one of your queues has a long wait time, you may use the Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo, and Horizon::routeSmsNotificationsTo methods. You may call these methods from your application’s AppServiceProvider:

Horizon::routeMailNotificationsTo(‘example@example.com’);
Horizon::routeSlackNotificationsTo(‘slack-webhook-url’, ‘#channel’);
Horizon::routeSmsNotificationsTo(‘15556667777’);
Configuring Notification Wait Time Thresholds
You may configure how many seconds are considered a “long wait” within your config/horizon.php configuration file. The waits configuration option within this file allows you to control the long wait threshold for each connection / queue combination:

‘waits’ => [
‘redis:default’ => 60,
],
Metrics
Horizon includes a metrics dashboard which provides information on your job and queue wait times and throughput. In order to populate this dashboard, you should configure Horizon’s snapshot Artisan command to run every five minutes via your application’s scheduler:

/**
* Define the application’s command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command(‘horizon:snapshot’)->everyFiveMinutes();
}

Envoy Task Runner

Introduction
Laravel Envoy provides a clean, minimal syntax for defining common tasks you run on your remote servers. Using Blade style syntax, you can easily setup tasks for deployment, Artisan commands, and more. Currently, Envoy only supports the Mac and Linux operating systems.

Installation
First, install Envoy using the Composer global require command:
composer global require laravel/envoy

Since global Composer libraries can sometimes cause package version conflicts, you may wish to consider using cgr, which is a drop-in replacement for the composer global require command. The cgr library’s installation instructions can be found on GitHub.

Updating Envoy
You may also use Composer to keep your Envoy installation up to date. Issuing the composer global update command will update all of your globally installed Composer packages:
composer global update

Writing Tasks
All of your Envoy tasks should be defined in an Envoy.blade.php file in the root of your project. Here’s an example to get you started:

@servers([‘web’ => [‘user@192.168.1.1’]])

@task(‘foo’, [‘on’ => ‘web’])
ls -la
@endtask
As you can see, an array of @servers is defined at the top of the file, allowing you to reference these servers in the on option of your task declarations. Within your @task declarations, you should place the Bash code that should run on your server when the task is executed.

You can force a script to run locally by specifying the server’s IP address as 127.0.0.1:

@servers([‘localhost’ => ‘127.0.0.1’])
Setup
Sometimes, you may need to execute some PHP code before executing your Envoy tasks. You may use the @setup directive to declare variables and do other general PHP work before any of your other tasks are executed:

Variables
If needed, you may pass option values into Envoy tasks using the command line:

envoy run deploy –branch=master
You may access the options in your tasks via Blade’s “echo” syntax. Of course, you may also use if statements and loops within your tasks. For example, let’s verify the presence of the $branch variable before executing the git pull command:

@servers([‘web’ => ‘192.168.1.1’])

@task(‘deploy’, [‘on’ => ‘web’])
cd site

@if ($branch)
git pull origin {{ $branch }}
@endif

php artisan migrate
@endtask

Notifications
Slack
Envoy also supports sending notifications to Slack after each task is executed. The @slack directive accepts a Slack hook URL and a channel name. You may retrieve your webhook URL by creating an “Incoming WebHooks” integration in your Slack control panel. You should pass the entire webhook URL into the @slack directive:

@finished
@slack(‘webhook-url’, ‘#bots’)
@endfinished
You may provide one of the following as the channel argument:

To send the notification to a channel: #channel
To send the notification to a user: @user