Readouble

Laravel 5.2 認可

イントロダクションIntroduction

Laravelは組み込み済みの認証サービスに加え、認可ロジックを取りまとめ、リソースへのアクセスをコントロールする簡単な手段を提供します。認可ロジックを組織立てるのに役立つメソッドやヘルパはたくさん用意されていますので、このドキュメントで紹介します。In addition to providing authentication[/docs/{{version}}/authentication] services out of the box, Laravel also provides a simple way to organize authorization logic and control access to resources. There are a variety of methods and helpers to assist you in organizing your authorization logic, and we'll cover each of them in this document.

アビリティの定義Defining Abilities

あるユーザが指定されたアクションを実行しても良いかをシンプルに判定するには、Illuminate\Auth\Access\Gateクラスを使い「アビリティ(ability)」を定義してください。Laravelに初めから用意されているAuthServiceProviderは、アプリケーションの全アビリティを定義するために便利な場所です。例として現在のUserPostモデルを受け取る、update-postアビリティを定義してみましょう。このアビリティの中で、ユーザのidがポストのuser_idと一致するかを判定します。The simplest way to determine if a user may perform a given action is to define an "ability" using the Illuminate\Auth\Access\Gate class. The AuthServiceProvider which ships with Laravel serves as a convenient location to define all of the abilities for your application. For example, let's define an update-post ability which receives the current User and a Post model[/docs/{{version}}/eloquent]. Within our ability, we will determine if the user's id matches the post's user_id:

<?php

namespace App\Providers;

use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * 全認証/認可サービスの登録
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function boot(GateContract $gate)
    {
        $this->registerPolicies($gate);

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

渡ってきた$userNULLではないかの、チェックを行っていないことに注目です。Gateはユーザが認証されていないか、forUserメソッドを使いユーザが指定されていない場合は、全アビリティから自動的にfalseを返します。Note that we did not check if the given $user is not NULL. The Gate will automatically return false for all abilities when there is not an authenticated user or a specific user has not been specified using the forUser method.

クラスベースのアビリティClass Based Abilities

認可のコールバックとして「クロージャ」を登録する方法に加え、クラス名とメソッドの文字列を引数に渡してもクラスメソッドを登録できます。必要であれば、クラスはサービスコンテナを利用し、依存解決されます。In addition to registering Closures as authorization callbacks, you may register class methods by passing a string containing the class name and the method. When needed, the class will be resolved via the service container[/docs/{{version}}/container]:

$gate->define('update-post', 'Class@method');

認可チェックの停止Intercepting Authorization Checks

場合により、特定のユーザに対しては全アビリティを許可したい場合があります。この場合は他の全認可チェックの前に実行されるコールバックを定義するbeforeメソッドを使ってください。Sometimes, you may wish to grant all abilities to a specific user. For this situation, 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;
    }
});

beforeコールバックがnullではない結果を返した場合、それをチェック結果として取り扱います。If the before callback returns a non-null result that result will be considered the result of the check.

afterメソッドを使い、全部の認可のチェックを行った後に実行するコールバックを定義できます。しかしafterのコールバックの中から認可チェックの結果を変更できません。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) {
    //
});

アビリティの確認Checking Abilities

Gateファサードによる確認Via The Gate Facade

アビリティを定義したら、さまざまな方法で「確認」できます。最初はGateファサードcheckallowdeniesメソッドを使う方法です。これらのメソッドはアビリティ名とコールバックに渡した引数を受け取ります。Gateが自動的に現在のユーザをコールバック渡す引数の先頭に付け加えるため、こうしたメソッドに現在のユーザを渡す必要はありません。ですから既に定義したupdate-postアビリティを確認する場合、deniesメソッドにはPostインスタンスを渡す必要があるだけです。Once an ability has been defined, we may "check" it in a variety of ways. First, we may use the check, allows, or denies methods on the Gate facade[/docs/{{version}}/facades]. All of these methods receive the name of the ability and the arguments that should be passed to the ability's callback. You do not need to pass the current user to these methods, since the Gate will automatically prepend the current user to the arguments passed to the callback. So, when checking the update-post ability we defined earlier, we only need to pass a Post instance to the denies method:

<?php

namespace App\Http\Controllers;

use Gate;
use App\User;
use App\Post;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * 指定したポストの更新
     *
     * @param  int  $id
     * @return Response
     */
    public function update($id)
    {
    	$post = Post::findOrFail($id);

    	if (Gate::denies('update-post', $post)) {
    		abort(403);
    	}

    	// ポスト更新処理…
    }
}

当然のことながら、allowsメソッドはdeniesメソッドをただひっくり返した働きをし、アクションが認可されていればtrueを返します。checkメソッドはallowsメソッドのエイリアスです。Of course, the allows method is simply the inverse of the denies method, and returns true if the action is authorized. The check method is an alias of the allows method.

特定ユーザのアビリティ確認Checking Abilities For Specific Users

現在認証されているユーザではなく、別のユーザが指定したアビリティを持っているかをGateファサードで確認したい場合は、forUserメソッドを使います。If you would like to use the Gate facade to check if a user other than the currently authenticated user has a given ability, you may use the forUser method:

if (Gate::forUser($user)->allows('update-post', $post)) {
	//
}

複数の引数の指定Passing Multiple Arguments

もちろんアビリティのコールバックには複数の引数が指定できます。Of course, ability callbacks may receive multiple arguments:

Gate::define('delete-comment', function ($user, $post, $comment) {
	//
});

アビリティで複数の引数が必要であれば、Gateファサードのメソッドに引数を配列として渡してください。If your ability needs multiple arguments, simply pass an array of arguments to the Gate methods:

if (Gate::allows('delete-comment', [$post, $comment])) {
	//
}

Userモデルによる確認Via The User Model

他のやり方として、アビリティをUserモデルインスタンスでも確認できます。LaravelのApp\Userモデルは、cancannotメソッドを提供しているAuthorizableトレイトをuseしています。これらのメソッドは、Gateファサードのallowdeniesメソッドと使い方が似ています。では、前の例と同様に、コードを次のように変更してみましょう。Alternatively, you may check abilities via the User model instance. By default, Laravel's App\User model uses an Authorizable trait which provides two methods: can and cannot. These methods may be used similarly to the allows and denies methods present on the Gate facade. So, using our previous example, we may modify our code like so:

<?php

namespace App\Http\Controllers;

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

class PostController extends Controller
{
    /**
     * 指定したポストの更新
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
    	$post = Post::findOrFail($id);

    	if ($request->user()->cannot('update-post', $post)) {
    		abort(403);
    	}

    	// ポストの更新処理…
    }
}

もちろん、canメソッドは単にcannotメソッドの真反対の働きです。Of course, the can method is simply the inverse of the cannot method:

if ($request->user()->can('update-post', $post)) {
	// Update Post...
}

Bladeテンプレートでの確認Within Blade Templates

現在の認証ユーザが指定したアビリティを持っているかを簡単に確認するのに便利なように、Laravelは@can Bladeディレクティブを用意しています。例を見てください。For convenience, Laravel provides the @can Blade directive to quickly check if the currently authenticated user has a given ability. For example:

<a href="/post/{{ $post->id }}">ポスト表示</a>

@can('update-post', $post)
	<a href="/post/{{ $post->id }}/edit">ポスト編集</a>
@endcan

@canディレクティブは、@elseディレクティブと組み合わせても使えます。You may also combine the @can directive with @else directive:

@can('update-post', $post)
	<!-- 現在のユーザはポストを更新可能 -->
@else
	<!-- 現在のユーザはポストを更新不可 -->
@endcan

フォームリクエストでの確認Within Form Requests

Gateで定義したアビリティをフォームリクエストauthorizeメソッドで活用する選択を取ることもできます。You may also choose to utilize your Gate defined abilities from a form request's[/docs/{{version}}/validation#form-request-validation] authorize method. For example:

/**
 * ユーザがこのリクエストを作成できる認可があるかの判定
 *
 * @return bool
 */
public function authorize()
{
    $postId = $this->route('post');

    return Gate::allows('update', Post::findOrFail($postId));
}

ポリシーPolicies

ポリシーの作成Creating Policies

全認可ロジックをAuthServiceProviderの中で定義するのは、大きなアプリケーションでは厄介ですから、Laravelでは認可ロジックを「ポリシー」クラスに分割できます。ポリシーは普通のPHPクラスで、認可するリソースに基づいてロジックをグループ分けするものです。Since defining all of your authorization logic in the AuthServiceProvider could become cumbersome in large applications, Laravel allows you to split your authorization logic into "Policy" classes. Policies are plain PHP classes that group authorization logic based on the resource they authorize.

始めにPostモデルの認可を管理するポリシーを生成しましょう。make:policy Artisanコマンドでポリシーを生成します。生成したポリシーはapp/Policiesディレクトリへ設置されます。First, let's generate a policy to manage authorization for our Post model. You may generate a policy using the make:policy artisan command[/docs/{{version}}/artisan]. The generated policy will be placed in the app/Policies directory:

php artisan make:policy PostPolicy

ポリシーの登録Registering Policies

ポリシーができたら、Gateクラスで登録する必要があります。AuthServiceProviderには様々なエンティティを管理するポリシーとマップするためのpoliciesプロパティを含んでいます。では、PostモデルのポリシーであるPostPolicyクラスを指定しましょう。Once the policy exists, we need to register it with the Gate class. The AuthServiceProvider contains a policies property which maps various entities to the policies that manage them. So, we will specify that the Post model's policy is the PostPolicy class:

<?php

namespace App\Providers;

use App\Post;
use App\Policies\PostPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * アプリケーションにマップするポリシー
     *
     * @var array
     */
    protected $policies = [
        Post::class => PostPolicy::class,
    ];

    /**
     * アプリケーションの全認証/認可サービスを登録
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function boot(GateContract $gate)
    {
        $this->registerPolicies($gate);
    }
}

ポリシーの記述Writing Policies

ポリシーを生成し登録したら、認可する各アビリティのためのメソッドを追加できます。指定したUserPostを「更新(update)」できるかを判定する、updateメソッドをPostPolicyに例として定義してみます。Once the policy has been generated and registered, we can add methods for each ability it authorizes. For example, let's define an update method on our PostPolicy, which will determine if the given User can "update" a Post:

<?php

namespace App\Policies;

use App\User;
use App\Post;

class PostPolicy
{
	/**
	 * ユーザにより指定ポストが更新できるかを判定
	 *
	 * @param  \App\User  $user
	 * @param  \App\Post  $post
	 * @return bool
	 */
    public function update(User $user, Post $post)
    {
    	return $user->id === $post->user_id;
    }
}

認可する様々なアビリティを必要なだけポリシーにメソッドとして追加定義してください。たとえばshowdestroyaddCommentメソッドなど、多様なPostアクションの認可が定義できるでしょう。You may continue to define additional methods on the policy as needed for the various abilities it authorizes. For example, you might define show, destroy, or addComment methods to authorize various Post actions.

注目: 全ポリシーはLaravelのサービスコンテナにより依存解決されます。つまりポリシーのコンストラクターに必要な依存をタイプヒントで指定すれば、自動的に挿入されます。Note: All policies are resolved via the Laravel service container[/docs/{{version}}/container], meaning you may type-hint any needed dependencies in the policy's constructor and they will be automatically injected.

全チェックの停止Intercepting All Checks

場合により特定のユーザにポリシーの全アビリティを許可したい場合があります。この状況ではポリシーにbeforeメソッドを定義してください。このメソッドはポリシーにある他の全認可チェックより先に実行されます。Sometimes, you may wish to grant all abilities to a specific user on a policy. For this situation, define a before method on the policy. This method will be run before all other authorization checks on the policy:

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

beforeメソッドがnullでない値を返した場合、それをチェックの結果として取り扱います。If the before method returns a non-null result that result will be considered the result of the check.

ポリシーの確認Checking Policies

ポリシーメソッドはクロージャベースの認可コールバックと全く同じ方法で呼び出します。GateファサードやUserモデル、@can Bladeディレクティブ、policyヘルパを使用できます。Policy methods are called in exactly the same way as Closure based authorization callbacks. You may use the Gate facade, the User model, the @can Blade directive, or the policy helper.

Gateファサードによる確認Via The Gate Facade

Gateはメソッドに渡された引数のクラスを調べ、どのポリシーを使用するか自動的に決定します。ですからPostインスタンスをdeniesメソッドに渡せば、Gateは認可するアクションに合ったPostPolicyを使用します。The Gate will automatically determine which policy to use by examining the class of the arguments passed to its methods. So, if we pass a Post instance to the denies method, the Gate will utilize the corresponding PostPolicy to authorize actions:

<?php

namespace App\Http\Controllers;

use Gate;
use App\User;
use App\Post;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * 指定ポストの更新
     *
     * @param  int  $id
     * @return Response
     */
    public function update($id)
    {
    	$post = Post::findOrFail($id);

    	if (Gate::denies('update', $post)) {
    		abort(403);
    	}

    	// ポストの更新処理…
    }
}

Userモデルによる確認Via The User Model

Userモデルのcancannotメソッドも引数に指定された引数に対する使用可能なポリシーがあれば、自動的に使用します。これらのメソッドはアプリケーションが取得したUserインスタンス全てに対するアクションを認可するために、便利な手法を提供しています。The User model's can and cannot methods will also automatically utilize policies when they are available for the given arguments. These methods provide a convenient way to authorize actions for any User instance retrieved by your application:

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

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

Bladeテンプレートでの確認Within Blade Templates

同様に、@can Bladeディレクティブも与えられた引数に対して使用可能なポリシーを活用します。Likewise, the @can Blade directive will utilize policies when they are available for the given arguments:

@can('update', $post)
	<!-- 現在のユーザはポストを更新できる -->
@endcan

policyヘルパによる確認Via The Policy Helper

グローバルなpolicyヘルパ関数は、指定されたクラスインスタンスに対する「ポリシー」クラスを取得するために使用します。例えば、Postインスタンスをpolicyヘルパに渡し、対応するPostPolicyクラスのインスタンスを取得できます。The global policy helper function may be used to retrieve the Policy class for a given class instance. For example, we may pass a Post instance to the policy helper to get an instance of our corresponding PostPolicy class:

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

コントローラの認可Controller Authorization

App\Http\Controllers\Controllerベースクラスはデフォルト状態で、Laravelが利用するAuthorizesRequestsトレイトを含んでいます。このトレイトは指定したアクションを簡単に認可するためのauthorizeメソッドを持っており、そのアクションを認可できない場合は、AuthorizationException例外を投げます。By default, the base App\Http\Controllers\Controller class included with Laravel uses the AuthorizesRequests trait. This trait provides the authorize method, which may be used to quickly authorize a given action and throw a AuthorizationException if the action is not authorized.

authorizeメソッドはGate::allows$user->can()などの認可メソッドと同じ使用方法です。では、Postを更新するリクエストを手っ取り早く認可するために、authorizeメソッドを用いてみましょう。The authorize method shares the same signature as the various other authorization methods such as Gate::allows and $user->can(). So, let's use the authorize method to quickly authorize a request to update a Post:

<?php

namespace App\Http\Controllers;

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

class PostController extends Controller
{
    /**
     * 指定したポストの更新
     *
     * @param  int  $id
     * @return Response
     */
    public function update($id)
    {
    	$post = Post::findOrFail($id);

    	$this->authorize('update', $post);

    	// ポストの更新処理…
    }
}

アクションが認可されていれば、コントローラは通常通り続けて実行されます。しかしauthorizeメソッドがアクションを非認可と判断すると、AuthorizationExceptionが自動的に投げられ、 403 Not AuthorizedステータスコードのHTTPレスポンスが生成されます。ご覧の通りにauthorizeメソッドはコード1行でアクションを認可し、例外を投げるための便利で手っ取り早い方法です。If the action is authorized, the controller will continue executing normally; however, if the authorize method determines that the action is not authorized, a AuthorizationException will automatically be thrown which generates a HTTP response with a 403 Not Authorized status code. As you can see, the authorize method is a convenient, fast way to authorize an action or throw an exception with a single line of code.

AuthorizesRequestsトレイトは、現在認証中ではない別のユーザのアクションを認可する、authorizeForUserメソッドも提供しています。The AuthorizesRequests trait also provides the authorizeForUser method to authorize an action on a user that is not the currently authenticated user:

$this->authorizeForUser($user, 'update', $post);

ポリシーメソッドの自動決定Automatically Determining Policy Methods

ポリシーのメソッドはコントローラのメソッドと頻繁に対応します。たとえば前記のupdateメソッドのように、updateと言う名前がコントローラメソッドとポリシーメソッドで共通です。Frequently, a policy's methods will correspond to the methods on a controller. For example, in the update method above, the controller method and the policy method share the same name: update.

そのため、Laravelはauthorizeメソッドの引数にインスタンスだけを渡すことも許しています。認可するアビリティは呼び出しているメソッドの名前を元に自動的に決められます。この例では、コントローラのupdateメソッドからauthorizeが呼びだされていますから、PostPolicy上でもupdateメソッドが呼びだされます。For this reason, Laravel allows you to simply pass the instance arguments to the authorize method, and the ability being authorized will automatically be determined based on the name of the calling function. In this example, since authorize is called from the controller's update method, the update method will also be called on the PostPolicy:

/**
 * 指定ポストの更新
 *
 * @param  int  $id
 * @return Response
 */
public function update($id)
{
	$post = Post::findOrFail($id);

	$this->authorize($post);

	// ポストの更新…
}

章選択

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作