Laravel Artisan Console

ついにDigging Deeperまできました。特に興味があるのは、Cache, mail, filestrage
broadcasting, collection, queuesは意味がわからん。他は重要度が不明。
まずArtisanから。

Introduction
Artisan is the command-line interface included with Laravel. It provides a number of helpful commands that can assist you while you build your application. To view a list of all available Artisan commands, you may use the list command:

php artisan list
Available commands:
clear-compiled Remove the compiled class file
down Put the application into maintenance mode
dump-server Start the dump server to collect dump information.
env Display the current framework environment
help Displays help for a command
inspire Display an inspiring quote
list Lists commands
migrate Run the database migrations
optimize Cache the framework bootstrap files
preset Swap the front-end scaffolding for the application
serve Serve the application on the PHP development server
tinker Interact with your application
up Bring the application out of maintenance mode
app
app:name Set the application namespace
auth
auth:clear-resets Flush expired password reset tokens
cache
cache:clear Flush the application cache
cache:forget Remove an item from the cache
cache:table Create a migration for the cache database table
config
config:cache Create a cache file for faster configuration loading
config:clear Remove the configuration cache file
db
db:seed Seed the database with records
event
event:generate Generate the missing events and listeners based on registration
key
key:generate Set the application key
make
make:auth Scaffold basic login and registration views and routes
make:channel Create a new channel class
make:command Create a new Artisan command
make:controller Create a new controller class
make:event Create a new event class
make:exception Create a new custom exception class
make:factory Create a new model factory
make:job Create a new job class
make:listener Create a new event listener class
make:mail Create a new email class
make:middleware Create a new middleware class
make:migration Create a new migration file
make:model Create a new Eloquent model class
make:notification Create a new notification class
make:observer Create a new observer class
make:policy Create a new policy class
make:provider Create a new service provider class
make:request Create a new form request class
make:resource Create a new resource
make:rule Create a new validation rule
make:seeder Create a new seeder class
make:test Create a new test class
migrate
migrate:fresh Drop all tables and re-run all migrations
migrate:install Create the migration repository
migrate:refresh Reset and re-run all migrations
migrate:reset Rollback all database migrations
migrate:rollback Rollback the last database migration
migrate:status Show the status of each migration
notifications
notifications:table Create a migration for the notifications table
optimize
optimize:clear Remove the cached bootstrap files
package
package:discover Rebuild the cached package manifest
queue
queue:failed List all of the failed queue jobs
queue:failed-table Create a migration for the failed queue jobs database table
queue:flush Flush all of the failed queue jobs
queue:forget Delete a failed queue job
queue:listen Listen to a given queue
queue:restart Restart queue worker daemons after their current job
queue:retry Retry a failed queue job
queue:table Create a migration for the queue jobs database table
queue:work Start processing jobs on the queue as a daemon
route
route:cache Create a route cache file for faster route registration
route:clear Remove the route cache file
route:list List all registered routes
schedule
schedule:finish Handle the completion of a scheduled command
schedule:run Run the scheduled commands
session
session:table Create a migration for the session database table
storage
storage:link Create a symbolic link from “public/storage” to “storage/app/public”
vendor
vendor:publish Publish any publishable assets from vendor packages
view
view:cache Compile all of the application’s Blade templates
view:clear Clear all compiled view files
makeが多いのと、意外とqueueがあるな。
php artisan help migrate

Laravel REPL
All Laravel applications include Tinker, a REPL powered by the PsySH package. Tinker allows you to interact with your entire Laravel application on the command line, including the Eloquent ORM, jobs, events, and more. To enter the Tinker environment, run the tinker Artisan command:
php artisan tinker

In addition to the commands provided with Artisan, you may also build your own custom commands. Commands are typically stored in the app/Console/Commands directory; however, you are free to choose your own storage location as long as your commands can be loaded by Composer.
ここまでいったらすげーわ。

Generating Commands
To create a new command, use the make:command Artisan command. This command will create a new command class in the app/Console/Commands directory. Don’t worry if this directory does not exist in your application, since it will be created the first time you run the make:command Artisan command. The generated command will include the default set of properties and methods that are present on all commands:
php artisan make:command SendEmails

After generating your command, you should fill in the signature and description properties of the class, which will be used when displaying your command on the list screen. The handle method will be called when your command is executed. You may place your command logic in this method.

Tip!! For greater code reuse, it is good practice to keep your console commands light and let them defer to application services to accomplish their tasks. In the example below, note that we inject a service class to do the “heavy lifting” of sending the e-mails.

Let’s take a look at an example command. Note that we are able to inject any dependencies we need into the command’s constructor or handle method. The Laravel service container will automatically inject all dependencies type-hinted in the constructor or handle method:

namespace App\Console\Commands;

use App\User;
use App\DripEmailer;
use Illuminate\Console\Command;

class SendEmails extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'email:send {user}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send drip e-mails to a user';

    /**
     * The drip e-mail service.
     *
     * @var DripEmailer
     */
    protected $drip;

    /**
     * Create a new command instance.
     *
     * @param  DripEmailer  $drip
     * @return void
     */
    public function __construct(DripEmailer $drip)
    {
        parent::__construct();

        $this->drip = $drip;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->drip->send(User::find($this->argument('user')));
    }
}

parent::__construct();の書き方はわからんぞ。

Closure Commands
Closure based commands provide an alternative to defining console commands as classes. In the same way that route Closures are an alternative to controllers, think of command Closures as an alternative to command classes. Within the commands method of your app/Console/Kernel.php file, Laravel loads the routes/console.php file:

protected function commands()
{
    require base_path('routes/console.php');
}

closureではなく、base_pathを定義します。

Even though this file does not define HTTP routes, it defines console based entry points (routes) into your application. Within this file, you may define all of your Closure based routes using the Artisan::command method. The command method accepts two arguments: the command signature and a Closure which receives the commands arguments and options:

rtisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
});

Type-Hinting Dependencies
In addition to receiving your command’s arguments and options, command Closures may also type-hint additional dependencies that you would like resolved out of the service container:

use App\User;
use App\DripEmailer;

Artisan::command(’email:send {user}’, function (DripEmailer $drip, $user) {
$drip->send(User::find($user));
});
Closure Command Descriptions
When defining a Closure based command, you may use the describe method to add a description to the command. This description will be displayed when you run the php artisan list or php artisan help commands:

Artisan::command(‘build {project}’, function ($project) {
$this->info(“Building {$project}!”);
})->describe(‘Build the project’);]
うおーなんか疲れたーーーーーーー

Laravel Resetting Passwords

resetって、単にpasswordをupdateすればいいだけじゃないのか?

Want to get started fast? Just run php artisan make:auth in a fresh Laravel application and navigate your browser to http://your-app.test/register or any other URL that is assigned to your application. This single command will take care of scaffolding your entire authentication system, including resetting passwords!

Most web applications provide a way for users to reset their forgotten passwords. Rather than forcing you to re-implement this on each application, Laravel provides convenient methods for sending password reminders and performing password resets.
確かにパスワード忘れることってよくあります。

Database Considerations
To get started, verify that your App\User model implements the Illuminate\Contracts\Auth\CanResetPassword contract. Of course, the App\User model included with the framework already implements this interface, and uses the Illuminate\Auth\Passwords\CanResetPassword trait to include the methods needed to implement the interface.

Generating The Reset Token Table Migration
Next, a table must be created to store the password reset tokens. The migration for this table is included with Laravel out of the box, and resides in the database/migrations directory. So, all you need to do is run your database migrations:
php artisan migrate
migrationってことあるごとにするんだ。tableを作成する度か。

Routing
Laravel includes Auth\ForgotPasswordController and Auth\ResetPasswordController classes that contains the logic necessary to e-mail password reset links and reset user passwords. All of the routes needed to perform password resets may be generated using the make:auth Artisan command:
php artisan make:auth
あれ、make:authは最初にログイン機能を実装する時だったはず。

Views
Again, Laravel will generate all of the necessary views for password reset when the make:auth command is executed. These views are placed in resources/views/auth/passwords. You are free to customize them as needed for your application.

After Resetting Passwords
Once you have defined the routes and views to reset your user’s passwords, you may access the route in your browser at /password/reset. The ForgotPasswordController included with the framework already includes the logic to send the password reset link e-mails, while the ResetPasswordController includes the logic to reset user passwords.

After a password is reset, the user will automatically be logged into the application and redirected to /home. You can customize the post password reset redirect location by defining a redirectTo property on the ResetPasswordController:

protected $redirectTo = ‘/dashboard’;
ああ、なるほど、reset用のviewをartisanで一発で作れるって意味か。すげー。

Customization
Authentication Guard Customization
In your auth.php configuration file, you may configure multiple “guards”, which may be used to define authentication behavior for multiple user tables. You can customize the included ResetPasswordController to use the guard of your choice by overriding the guard method on the controller. This method should return a guard instance:

use Illuminate\Support\Facades\Auth;

protected function guard()
{
    return Auth::guard('guard-name');
}

Password Broker Customization
In your auth.php configuration file, you may configure multiple password “brokers”, which may be used to reset passwords on multiple user tables. You can customize the included ForgotPasswordController and ResetPasswordController to use the broker of your choice by overriding the broker method:

use Illuminate\Support\Facades\Password;

/**
 * Get the broker to be used during password reset.
 *
 * @return PasswordBroker
 */
protected function broker()
{
    return Password::broker('name');
}

Laravel Hashing

「ハッシュ化」とは、「元データ」をハッシュアルゴリズム(md5、sha1、sha2等)に従って、固定長のランダムに見える値に「不可逆変換」する行為
Google検索もデータをhash化してるんじゃなかったっけ。

Introduction
The Laravel Hash facade provides secure Bcrypt and Argon2 hashing for storing user passwords. If you are using the built-in LoginController and RegisterController classes that are included with your Laravel application, they will use Bcrypt for registration and authentication by default.

Tip!! Bcrypt is a great choice for hashing passwords because its “work factor” is adjustable, which means that the time it takes to generate a hash can be increased as hardware power increases.

Bcrypt、Argon2? パスワード保存に使うアルゴリズム。なるほど。
Argon2は2015年7月に開催されたパスワードハッシュ競技会(英語版)で優勝した鍵導出関数
なるほどー、面白いね、この分野。

Basic Usage
You may hash a password by calling the make method on the Hash facade:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Controller;

class UpdatePasswordController extends Controller
{
    /**
     * Update the password for the user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        // Validate the new password length...

        $request->user()->fill([
            'password' => Hash::make($request->newPassword)
        ])->save();
    }
}

Hash::make($request->newPassword)って、ナニコレ。passwordをhash化してるってこと?
確かにDBにはハッシュ化された値です。

Adjusting The Bcrypt Work Factor
If you are using the Bcrypt algorithm, the make method allows you to manage the work factor of the algorithm using the rounds option; however, the default is acceptable for most applications:

$hashed = Hash::make('password', [
    'rounds' => 12
]);

ぬお、覚えること多すぎる。
Adjusting The Argon2 Work Factor
If you are using the Argon2 algorithm, the make method allows you to manage the work factor of the algorithm using the memory, time, and threads options; however, the defaults are acceptable for most applications:

$hashed = Hash::make('password', [
    'memory' => 1024,
    'time' => 2,
    'threads' => 2,
]);

ハッシュ化のアルゴリズム、チューニングできるんか。おもろ。

Verifying A Password Against A Hash
The check method allows you to verify that a given plain-text string corresponds to a given hash. However, if you are using the LoginController included with Laravel, you will probably not need to use this directly, as this controller automatically calls this method:

if (Hash::check('plain-text', $hashedPassword)) {
    // The passwords match...
}

Checking If A Password Needs To Be Rehashed
The needsRehash function allows you to determine if the work factor used by the hasher has changed since the password was hashed:

if (Hash::needsRehash($hashed)) {
    $hashed = Hash::make('plain-text');
}

Laravel Encryption

しかしdocumentの量多いな
これlaravel開発者が作ってるんだろうか。まあ、関わってることは確かだな。そう思うとテンションがあがります。

Introduction
Laravel’s encrypter uses OpenSSL to provide AES-256 and AES-128 encryption. You are strongly encouraged to use Laravel’s built-in encryption facilities and not attempt to roll your own “home grown” encryption algorithms. All of Laravel’s encrypted values are signed using a message authentication code (MAC) so that their underlying value can not be modified once encrypted.
AES-256:AES(Advanced Encryption Standard)と呼ばれる暗号化方式のうち、256ビット長の暗号鍵を使用する方式
AES-128:Advanced Encryption Standard (AES) は、DESに代わる新しい標準暗号となる共通鍵暗号アルゴリズム

暗号化は少し勉強したけど、この分野、奥がすげー深いからな。片足踏み入れると抜け出せなくなる。

Configuration
Before using Laravel’s encrypter, you must set a key option in your config/app.php configuration file. You should use the php artisan key:generate command to generate this key since this Artisan command will use PHP’s secure random bytes generator to build your key. If this value is not properly set, all values encrypted by Laravel will be insecure.
linuxの公開鍵、秘密鍵の仕組みと似てる。

Using The Encrypter
Encrypting A Value
You may encrypt a value using the encrypt helper. All encrypted values are encrypted using OpenSSL and the AES-256-CBC cipher. Furthermore, all encrypted values are signed with a message authentication code (MAC) to detect any modifications to the encrypted string:

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Store a secret message for the user.
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function storeSecret(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $user->fill([
            'secret' => encrypt($request->secret)
        ])->save();
    }
}

encrypt($request->secret)って関数があるから、encryptって作ってるんだろうな。凄い。

Encrypting Without Serialization
Encrypted values are passed through serialize during encryption, which allows for encryption of objects and arrays. Thus, non-PHP clients receiving encrypted values will need to unserialize the data. If you would like to encrypt and decrypt values without serialization, you may use the encryptString and decryptString methods of the Crypt facade:

use Illuminate\Support\Facades\Crypt;

$encrypted = Crypt::encryptString('Hello world.');
$decrypted = Crypt::decryptString($encrypted);

encryptとdecrptってなんだっけ。これ、encode, decodeみたいなもん?

Decrypting A Value
You may decrypt values using the decrypt helper. If the value can not be properly decrypted, such as when the MAC is invalid, an Illuminate\Contracts\Encryption\DecryptException will be thrown:

use Illuminate\Contracts\Encryption\DecryptException;

try {
    $decrypted = decrypt($encryptedValue);
} catch (DecryptException $e) {
    //
}

暗号化って、アプリケーションの中でどう使うかですな。
セキュアな通信に使いたいのはわかるが、アプリケーション内でdecrypt, cryptするイメージが湧かない。

Laravel Email Verification

Introduction
Many web applications require users to verify their email addresses before using the application. Rather than forcing you to re-implement this on each application, Laravel provides convenient methods for sending and verifying email verification requests.
Email Verificationって、メールアドレスかどうかの判定ってこと?不正メールか、スパムメールかなども含まれるのか?でもSMTPだけだから、アドレス判定だけだろうか。

To get started, verify that your App\User model implements the Illuminate\Contracts\Auth\MustVerifyEmail contract:

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;
    // ...
}

MustVerifyEmail って、verify必須に見える。

The Email Verification Column
Next, your user table must contain an email_verified_at column to store the date and time that the email address was verified. By default, the users table migration included with the Laravel framework already includes this column. So, all you need to do is run your database migrations:
email_verified_at column って、単にemailのカラムじゃあかんの?
php artisan migrate

Routing
Laravel includes the Auth\VerificationController class that contains the necessary logic to send verification links and verify emails. To register the necessary routes for this controller, pass the verify option to the Auth::routes method:
Auth::routes([‘verify’ => true]);
説明がえらい雑だな。

Protecting Routes
Route middleware can be used to only allow verified users to access a given route. Laravel ships with a verified middleware, which is defined at Illuminate\Auth\Middleware\EnsureEmailIsVerified. Since this middleware is already registered in your application’s HTTP kernel, all you need to do is attach the middleware to a route definition:

Route::get('profile', function () {
    // Only verified users may enter...
})->middleware('verified');

Views
Laravel will generate all of the necessary email verification views when the make:auth command is executed. This view is placed in resources/views/auth/verify.blade.php. You are free to customize this view as needed for your application.

After Verifying Emails
After an email address is verified, the user will automatically be redirected to /home. You can customize the post verification redirect location by defining a redirectTo method or property on the VerificationController:

protected $redirectTo = ‘/dashboard’;
redirectはroutingのredirectと全く同じ

Events
Laravel dispatches events during the email verification process. You may attach listeners to these events in your EventServiceProvider:

protected $listen = [
    'Illuminate\Auth\Events\Verified' => [
        'App\Listeners\LogVerifiedUser',
    ],
];

email varifyは割と簡単・シンプルのようです。

Laravel Authorization

Introduction
In addition to providing authentication services out of the box, Laravel also provides a simple way to authorize user actions against a given resource. Like authentication, Laravel’s approach to authorization is simple, and there are two primary ways of authorizing actions: gates and policies.

Think of gates and policies like routes and controllers. Gates provide a simple, Closure based approach to authorization while policies, like controllers, group their logic around a particular model or resource. We’ll explore gates first and then examine policies.

You do not need to choose between exclusively using gates or exclusively using policies when building an application. Most applications will most likely contain a mixture of gates and policies, and that is perfectly fine! Gates are most applicable to actions which are not related to any model or resource, such as viewing an administrator dashboard. In contrast, policies should be used when you wish to authorize an action for a particular model or resource.

Gates
Writing Gates
Gates are Closures that determine if a user is authorized to perform a given action and are typically defined in the App\Providers\AuthServiceProvider class using the Gate facade. Gates always receive a user instance as their first argument, and may optionally receive additional arguments such as a relevant Eloquent model:

public function boot()
{
    $this->registerPolicies();

    Gate::define('update-post', function ($user, $post) {
        return $user->id == $post->user_id;
    });
}

Gates may also be defined using a Class@method style callback string, like controllers:

Resource Gates
You may also define multiple Gate abilities at once using the resource method:

Gate::resource(‘posts’, ‘App\Policies\PostPolicy’);
This is identical to manually defining the following Gate definitions:

Gate::define('posts.view', 'App\Policies\PostPolicy@view');
Gate::define('posts.create', 'App\Policies\PostPolicy@create');
Gate::define('posts.update', 'App\Policies\PostPolicy@update');
Gate::define('posts.delete', 'App\Policies\PostPolicy@delete');

By default, the view, create, update, and delete abilities will be defined. You may override the default abilities by passing an array as a third argument to the resource method. The keys of the array define the names of the abilities while the values define the method names. For example, the following code will only create two new Gate definitions – posts.image and posts.photo:

Gate::resource('posts', 'PostPolicy', [
    'image' => 'updateImage',
    'photo' => 'updatePhoto',
]);

Authorizing Actions
To authorize an action using gates, you should use the allows or denies methods. Note that you are not required to pass the currently authenticated user to these methods. Laravel will automatically take care of passing the user into the gate Closure:

if (Gate::allows('update-post', $post)) {
    // The current user can update the post...
}

if (Gate::denies('update-post', $post)) {
    // The current user can't update the post...
}
if (Gate::forUser($user)->allows('update-post', $post)) {
    // The user can update the post...
}

if (Gate::forUser($user)->denies('update-post', $post)) {
    // The user can't update the post...
}

Intercepting Gate Checks
Sometimes, you may wish to grant all abilities to a specific user. You may use the before method to define a callback that is run before all other authorization checks:

Gate::before(function ($user, $ability) {
if ($user->isSuperAdmin()) {
return true;
}
});
If the before callback returns a non-null result that result will be considered the result of the check.

You may use the after method to define a callback to be executed after every authorization check. However, you may not modify the result of the authorization check from an after callback:

Gate::after(function ($user, $ability, $result, $arguments) {
    //
});

Creating Policies
Generating Policies
Policies are classes that organize authorization logic around a particular model or resource. For example, if your application is a blog, you may have a Post model and a corresponding PostPolicy to authorize user actions such as creating or updating posts.

You may generate a policy using the make:policy artisan command. The generated policy will be placed in the app/Policies directory. If this directory does not exist in your application, Laravel will create it for you:

php artisan make:policy PostPolicy
The make:policy command will generate an empty policy class. If you would like to generate a class with the basic “CRUD” policy methods already included in the class, you may specify a –model when executing the command:

php artisan make:policy PostPolicy –model=Post
Tip!! All policies are resolved via the Laravel service container, allowing you to type-hint any needed dependencies in the policy’s constructor to have them automatically injected.
artisanのコメントがわからんな。

Registering Policies
Once the policy exists, it needs to be registered. The AuthServiceProvider included with fresh Laravel applications contains a policies property which maps your Eloquent models to their corresponding policies. Registering a policy will instruct Laravel which policy to utilize when authorizing actions against a given model:

use App\Post;
use App\Policies\PostPolicy;
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 = [
        Post::class => PostPolicy::class,
    ];

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

        //
    }
}

policyでPost::class を PostPolicy::class にしてるってこと。Postは元からあるやつちゃんうか。
Writing Policies
Policy Methods
Once the policy has been registered, you may add methods for each action it authorizes. For example, let’s define an update method on our PostPolicy which determines if a given User can update a given Post instance.

The update method will receive a User and a Post instance as its arguments, and should return true or false indicating whether the user is authorized to update the given Post. So, for this example, let’s verify that the user’s id matches the user_id on the post:
なんか、blogベースで話が進んでいるが、updateはデータベースのupdateって意味でOK?

namespace App\Policies;

use App\User;
use App\Post;

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

updateはfunctionのupdateだ。

You may continue to define additional methods on the policy as needed for the various actions it authorizes. For example, you might define view or delete methods to authorize various Post actions, but remember you are free to give your policy methods any name you like.

Tip!! If you used the –model option when generating your policy via the Artisan console, it will already contain methods for the view, create, update, delete, restore, and forceDelete actions.
mysqlにviewなんてコマンドなかったはず。なんか眠くなってきたぞ。

Methods Without Models
Some policy methods only receive the currently authenticated user and not an instance of the model they authorize. This situation is most common when authorizing create actions. For example, if you are creating a blog, you may wish to check if a user is authorized to create any posts at all.

When defining policy methods that will not receive a model instance, such as a create method, it will not receive a model instance. Instead, you should define the method as only expecting the authenticated user:
modelなしのmethodって、そんなん可能なんかい。

Guest Users
By default, all gates and policies automatically return false if the incoming HTTP request was not initiated by an authenticated user. However, you may allow these authorization checks to pass through to your gates and policies by declaring an “optional” type-hint or supplying a null default value for the user argument definition:
guestユーザーってどういうこと。artisan:authしてるのに?オプションでできるってことか。

namespace App\Policies;

use App\User;
use App\Post;

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(?User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

Policy Filters
For certain users, you may wish to authorize all actions within a given policy. To accomplish this, define a before method on the policy. The before method will be executed before any other methods on the policy, giving you an opportunity to authorize the action before the intended policy method is actually called. This feature is most commonly used for authorizing application administrators to perform any action:

public function before($user, $ability)
{
    if ($user->isSuperAdmin()) {
        return true;
    }
}

superAdminか確認してるのはわかるが、superAdminってlaravelデフォルトのロール?

If you would like to deny all authorizations for a user you should return false from the before method. If null is returned, the authorization will fall through to the policy method.
相変わらず機能多いなー

Authorizing Actions Using Policies
Via The User Model
The User model that is included with your Laravel application includes two helpful methods for authorizing actions: can and cant. The can method receives the action you wish to authorize and the relevant model. For example, let’s determine if a user is authorized to update a given Post model:
policyを使ってauthorize ってことはpolicy重要じゃん。流してた。

if ($user->can('update', $post)) {
    //
}

can, cantはシンプルだなー

If a policy is registered for the given model, the can method will automatically call the appropriate policy and return the boolean result. If no policy is registered for the model, the can method will attempt to call the Closure based Gate matching the given action name.

Actions That Don’t Require Models
Remember, some actions like create may not require a model instance. In these situations, you may pass a class name to the can method. The class name will be used to determine which policy to use when authorizing the action:

use App\Post;

if ($user->can('create', Post::class)) {
    // Executes the "create" method on the relevant policy...
}

modelを使わない意味がわからん。

Via Middleware
Laravel includes a middleware that can authorize actions before the incoming request even reaches your routes or controllers. By default, the Illuminate\Auth\Middleware\Authorize middleware is assigned the can key in your App\Http\Kernel class. Let’s explore an example of using the can middleware to authorize that a user can update a blog post:

use App\Post;

Route::put('/post/{post}', function (Post $post) {
    // The current user may update the post...
})->middleware('can:update,post');

In this example, we’re passing the can middleware two arguments. The first is the name of the action we wish to authorize and the second is the route parameter we wish to pass to the policy method. In this case, since we are using implicit model binding, a Post model will be passed to the policy method. If the user is not authorized to perform the given action, a HTTP response with a 403 status code will be generated by the middleware.
Routeの後にmiddleware(‘can:update,post’);としてます。

Actions That Don’t Require Models
Again, some actions like create may not require a model instance. In these situations, you may pass a class name to the middleware. The class name will be used to determine which policy to use when authorizing the action:

Route::post(‘/post’, function () {
// The current user may create posts…
})->middleware(‘can:create,App\Post’);

Via Controller Helpers
In addition to helpful methods provided to the User model, Laravel provides a helpful authorize method to any of your controllers which extend the App\Http\Controllers\Controller base class. Like the can method, this method accepts the name of the action you wish to authorize and the relevant model. If the action is not authorized, the authorize method will throw an Illuminate\Auth\Access\AuthorizationException, which the default Laravel exception handler will convert to an HTTP response with a 403 status code:
403はページがない時だったような。

namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Update the given blog post.
     *
     * @param  Request  $request
     * @param  Post  $post
     * @return Response
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function update(Request $request, Post $post)
    {
        $this->authorize('update', $post);

        // The current user can update the blog post...
    }
}

感覚的には理解できるが、わかってない。
Actions That Don’t Require Models
As previously discussed, some actions like create may not require a model instance. In these situations, you may pass a class name to the authorize method. The class name will be used to determine which policy to use when authorizing the action:

public function create(Request $request)
{
    $this->authorize('create', Post::class);

    // The current user can create blog posts...
}

Via Blade Templates
When writing Blade templates, you may wish to display a portion of the page only if the user is authorized to perform a given action. For example, you may wish to show an update form for a blog post only if the user can actually update the post. In this situation, you may use the @can and @cannot family of directives:
bladeでも基本は一緒か。

@can('update', $post)
    <!-- The Current User Can Update The Post -->
@elsecan('create', App\Post::class)
    <!-- The Current User Can Create New Post -->
@endcan

@cannot('update', $post)
    <!-- The Current User Can't Update The Post -->
@elsecannot('create', App\Post::class)
    <!-- The Current User Can't Create New Post -->
@endcannot

Actions That Don’t Require Models
Like most of the other authorization methods, you may pass a class name to the @can and @cannot directives if the action does not require a model instance:

@can(‘create’, App\Post::class)

@endcan

@cannot(‘create’, App\Post::class)

@endcannot
なんか、コードの中にcan, cannotを書くのって、変な気分だなーー、他の言語で見かけないからかな。

Token Scopes

Scopes allow your API clients to request a specific set of permissions when requesting authorization to access an account. For example, if you are building an e-commerce application, not all API consumers will need the ability to place orders. Instead, you may allow the consumers to only request authorization to access order shipment statuses. In other words, scopes allow your application’s users to limit the actions a third-party application can perform on their behalf.

Defining Scopes
You may define your API’s scopes using the Passport::tokensCan method in the boot method of your AuthServiceProvider. The tokensCan method accepts an array of scope names and scope descriptions. The scope description may be anything you wish and will be displayed to users on the authorization approval screen:

use Laravel\Passport\Passport;

Passport::tokensCan([
    'place-orders' => 'Place orders',
    'check-status' => 'Check order status',
]);

Assigning Scopes To Tokens
When Requesting Authorization Codes
When requesting an access token using the authorization code grant, consumers should specify their desired scopes as the scope query string parameter. The scope parameter should be a space-delimited list of scopes:

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'client-id',
        'redirect_uri' => 'http://example.com/callback',
        'response_type' => 'code',
        'scope' => 'place-orders check-status',
    ]);

    return redirect('http://your-app.com/oauth/authorize?'.$query);
});

Checking Scopes
Passport includes two middleware that may be used to verify that an incoming request is authenticated with a token that has been granted a given scope. To get started, add the following middleware to the $routeMiddleware property of your app/Http/Kernel.php file:

‘scopes’ => \Laravel\Passport\Http\Middleware\CheckScopes::class,
‘scope’ => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
Check For All Scopes
The scopes middleware may be assigned to a route to verify that the incoming request’s access token has all of the listed scopes:

Route::get(‘/orders’, function () {
// Access token has both “check-status” and “place-orders” scopes…
})->middleware(‘scopes:check-status,place-orders’);
Check For Any Scopes
The scope middleware may be assigned to a route to verify that the incoming request’s access token has at least one of the listed scopes:

Route::get(‘/orders’, function () {
// Access token has either “check-status” or “place-orders” scope…
})->middleware(‘scope:check-status,place-orders’);
Checking Scopes On A Token Instance
Once an access token authenticated request has entered your application, you may still check if the token has a given scope using the tokenCan method on the authenticated User instance:

use Illuminate\Http\Request;

Route::get(‘/orders’, function (Request $request) {
if ($request->user()->tokenCan(‘place-orders’)) {
//
}
});
Additional Scope Methods
The scopeIds method will be return an array of all defined IDs / names:

Laravel\Passport\Passport::scopeIds();
The scopes method will return an array of all defined scopes as instances of Laravel\Passport\Scope:

Laravel\Passport\Passport::scopes();
The scopesFor method will return an array of Laravel\Passport\Scope instances matching the given IDs / names:

Laravel\Passport\Passport::scopesFor([‘place-orders’, ‘check-status’]);
You may determine if a given scope has been defined using the hasScope method:

Laravel\Passport\Passport::hasScope(‘place-orders’);
Consuming Your API With JavaScript
When building an API, it can be extremely useful to be able to consume your own API from your JavaScript application. This approach to API development allows your own application to consume the same API that you are sharing with the world. The same API may be consumed by your web application, mobile applications, third-party applications, and any SDKs that you may publish on various package managers.

Typically, if you want to consume your API from your JavaScript application, you would need to manually send an access token to the application and pass it with each request to your application. However, Passport includes a middleware that can handle this for you. All you need to do is add the CreateFreshApiToken middleware to your web middleware group in your app/Http/Kernel.php file:

‘web’ => [
// Other middleware…
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
Note: You should ensure that the EncryptCookies middleware is listed prior to the CreateFreshApiToken middleware in your middleware stack.

This Passport middleware will attach a laravel_token cookie to your outgoing responses. This cookie contains an encrypted JWT that Passport will use to authenticate API requests from your JavaScript application. Now, you may make requests to your application’s API without explicitly passing an access token:

axios.get(‘/api/user’)
.then(response => {
console.log(response.data);
});
Customizing The Cookie Name
If needed, you can customize the laravel_token cookie’s name using the Passport::cookie method. Typically, this method should be called from the boot method of your AuthServiceProvider:

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

Passport::routes();

Passport::cookie(‘custom_name’);
}
CSRF Protection
When using this method of authentication, the default Laravel JavaScript scaffolding instructs Axios to always send the X-CSRF-TOKEN and X-Requested-With headers. However, you should be sure to include your CSRF token in a HTML meta tag:

window.axios.defaults.headers.common = {
‘X-Requested-With’: ‘XMLHttpRequest’,
};
Events
Passport raises events when issuing access tokens and refresh tokens. You may use these events to prune or revoke other access tokens in your database. You may attach listeners to these events in your application’s EventServiceProvider:

/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
‘Laravel\Passport\Events\AccessTokenCreated’ => [
‘App\Listeners\RevokeOldTokens’,
],

‘Laravel\Passport\Events\RefreshTokenCreated’ => [
‘App\Listeners\PruneOldTokens’,
],
];
Testing
Passport’s actingAs method may be used to specify the currently authenticated user as well as its scopes. The first argument given to the actingAs method is the user instance and the second is an array of scopes that should be granted to the user’s token:

use App\User;
use Laravel\Passport\Passport;

public function testServerCreation()
{
Passport::actingAs(
factory(User::class)->create(),
[‘create-servers’]
);

$response = $this->post(‘/api/create-server’);

$response->assertStatus(201);
}
ぬお、なんか今日は無償に疲れた。

Laravel Personal Access Tokens

Sometimes, your users may want to issue access tokens to themselves without going through the typical authorization code redirect flow. Allowing users to issue tokens to themselves via your application’s UI can be useful for allowing users to experiment with your API or may serve as a simpler approach to issuing access tokens in general

Creating A Personal Access Client
Before your application can issue personal access tokens, you will need to create a personal access client. You may do this using the passport:client command with the –personal option. If you have already run the passport:install command, you do not need to run this command:

Managing Personal Access Tokens
Once you have created a personal access client, you may issue tokens for a given user using the createToken method on the User model instance. The createToken method accepts the name of the token as its first argument and an optional array of scopes as its second argument:

$user = App\User::find(1);

// Creating a token without scopes...
$token = $user->createToken('Token Name')->accessToken;

// Creating a token with scopes...
$token = $user->createToken('My Token', ['place-orders'])->accessToken;

SON API
Passport also includes a JSON API for managing personal access tokens. You may pair this with your own frontend to offer your users a dashboard for managing personal access tokens. Below, we’ll review all of the API endpoints for managing personal access tokens. 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.

Tip!! If you don’t want to implement the personal access token frontend yourself, you can use the frontend quickstart to have a fully functional frontend in a matter of minutes.

GET /oauth/scopes
This route returns all of the scopes defined for your application. You may use this route to list the scopes a user may assign to a personal access token:

axios.get('/oauth/scopes')
    .then(response => {
        console.log(response.data);
    });

GET /oauth/personal-access-tokens
This route returns all of the personal access tokens that the authenticated user has created. This is primarily useful for listing all of the user’s tokens so that they may edit or delete them:

const data = {
name: ‘Token Name’,
scopes: []
};

axios.post(‘/oauth/personal-access-tokens’, data)
.then(response => {
console.log(response.data.accessToken);
})
.catch (response => {
// List errors on response…
});
DELETE /oauth/personal-access-tokens/{token-id}
This route may be used to delete personal access tokens:

axios.delete(‘/oauth/personal-access-tokens/’ + tokenId);

Via Middleware
Passport includes an authentication guard that will validate access tokens on incoming requests. Once you have configured the api guard to use the passport driver, you only need to specify the auth:api middleware on any routes that require a valid access token:

Route::get('/user', function () {
    //
})->middleware('auth:api');

Passing The Access Token
When calling routes that are protected by Passport, your application’s API consumers should specify their access token as a Bearer token in the Authorization header of their request. For example, when using the Guzzle HTTP library:

$response = $client->request('GET', '/api/user', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],
]);

Password Grant Tokens

The OAuth2 password grant allows your other first-party clients, such as a mobile application, to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire OAuth2 authorization code redirect flow.

Creating A Password Grant Client
Before your application can issue tokens via the password grant, you will need to create a password grant client. You may do this using the passport:client command with the –password option. If you have already run the passport:install command, you do not need to run this command:
php artisan passport:client –password

Requesting Tokens
Once you have created a password grant client, you may request an access token by issuing a POST request to the /oauth/token route with the user’s email address and password. Remember, this route is already registered by the Passport::routes method so there is no need to define it manually. If the request is successful, you will receive an access_token and refresh_token in the JSON response from the server:

$http = new GuzzleHttp\Client;

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'taylor@laravel.com',
        'password' => 'my-password',
        'scope' => '',
    ],
]);

return json_decode((string) $response->getBody(), true);

Tip!! Remember, access tokens are long-lived by default. However, you are free to configure your maximum access token lifetime if needed.
Requesting All Scopes
When using the password grant, you may wish to authorize the token for all of the scopes supported by your application. You can do this by requesting the * scope. If you request the * scope, the can method on the token instance will always return true. This scope may only be assigned to a token that is issued using the password grant:

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'taylor@laravel.com',
        'password' => 'my-password',
        'scope' => '*',
    ],
]);

Implicit Grant Tokens
The implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can’t be securely stored. To enable the grant, call the enableImplicitGrant method in your AuthServiceProvider:

public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    Passport::enableImplicitGrant();
}
Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'client-id',
        'redirect_uri' => 'http://example.com/callback',
        'response_type' => 'token',
        'scope' => '',
    ]);

    return redirect('http://your-app.com/oauth/authorize?'.$query);
});

Client Credentials Grant Tokens
The client credentials grant is suitable for machine-to-machine authentication. For example, you might use this grant in a scheduled job which is performing maintenance tasks over an API.

Before your application can issue tokens via the client credentials grant, you will need to create a client credentials grant client. You may do this using the –client option of the passport:client command:

php artisan passport:client –client
Next, to use this grant type, you need to add the CheckClientCredentials middleware to the $routeMiddleware property of your app/Http/Kernel.php file:

Retrieving Tokens
To retrieve a token using this grant type, make a request to the oauth/token endpoint:

$guzzle = new GuzzleHttp\Client;

$response = $guzzle->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'client_credentials',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'scope' => 'your-scope',
    ],
]);

return json_decode((string) $response->getBody(), true)['access_token'];

Laravel 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));
}

ExpireInだと、Cookieのexpireみたいだ。
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.
access tokenの扱い
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
だいたい、php artisanコマンドが用意されてんな。

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:
http://example.com/callback,http://examplefoo.com/callback
Note: Any URLs which contains commas must be encoded.

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.

Tip!! If you don’t want to implement the entire client management frontend yourself, you can use the frontend quickstart to have a fully functional frontend in a matter of minutes.

GET /oauth/clients
This route returns all of the clients for the authenticated user. This is primarily useful for listing all of the user’s clients so that they may edit or delete them:

POST /oauth/clients
This route is used to create new clients. It requires two pieces of data: the client’s name and a redirect URL. The redirect URL is where the user will be redirected after approving or denying a request for authorization.

When a client is created, it will be issued a client ID and client secret. These values will be used when requesting access tokens from your application. The client creation route will return the new client instance:

const data = {
    name: 'Client Name',
    redirect: 'http://example.com/callback'
};

axios.post('/oauth/clients', data)
    .then(response => {
        console.log(response.data);
    })
    .catch (response => {
        // List errors on response...
    });

This route is used to update clients. It requires two pieces of data: the client’s name and a redirect URL. The redirect URL is where the user will be redirected after approving or denying a request for authorization. The route will return the updated client instance:
ああ、懐かしい、やったなー。触らないと、すっかり忘れる。

const data = {
    name: 'New Client Name',
    redirect: 'http://example.com/callback'
};

axios.put('/oauth/clients/' + clientId, data)
    .then(response => {
        console.log(response.data);
    })
    .catch (response => {
        // List errors on response...
    });

axios.delete('/oauth/clients/' + clientId)
    .then(response => {
        //
    });

Redirecting For Authorization
Once a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. First, the consuming application should make a redirect request to your application’s /oauth/authorize route like so:

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'client-id',
        'redirect_uri' => 'http://example.com/callback',
        'response_type' => 'code',
        'scope' => '',
    ]);

    return redirect('http://your-app.com/oauth/authorize?'.$query);
});

When receiving authorization requests, Passport will automatically display a template to the user allowing them to approve or deny the authorization request. If they approve the request, they will be redirected back to the redirect_uri that was specified by the consuming application. The redirect_uri must match the redirect URL that was specified when the client was created.

If you would like to customize the authorization approval screen, you may publish Passport’s views using the vendor:publish Artisan command. The published views will be placed in resources/views/vendor/passport:

php artisan vendor:publish --tag=passport-views

If the user approves the authorization request, they will be redirected back to the consuming application. The consumer should then issue a POST request to your application to request an access token. The request should include the authorization code that was issued by your application when the user approved the authorization request. In this example, we’ll use the Guzzle HTTP library to make the POST request:

Route::get('/callback', function (Request $request) {
    $http = new GuzzleHttp\Client;

    $response = $http->post('http://your-app.com/oauth/token', [
        'form_params' => [
            'grant_type' => 'authorization_code',
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
            'redirect_uri' => 'http://example.com/callback',
            'code' => $request->code,
        ],
    ]);

    return json_decode((string) $response->getBody(), true);
});

Like the /oauth/authorize route, the /oauth/token route is defined for you by the Passport::routes method. There is no need to manually define this route. By default, this route is throttled using the settings of the ThrottleRequests middleware.

If your application issues short-lived access tokens, users will need to refresh their access tokens via the refresh token that was provided to them when the access token was issued. In this example, we’ll use the Guzzle HTTP library to refresh the token:

$http = new GuzzleHttp\Client;

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'refresh_token',
        'refresh_token' => 'the-refresh-token',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'scope' => '',
    ],
]);

return json_decode((string) $response->getBody(), true);

This /oauth/token route will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.