本記事では、ブログ投稿システムを作りながらLaravelの認可機能の実装の仕方をわかりやすく解説していきます。
以下の記事の続きです。まだ読んでいない方はぜひご一読ください!
初心者の方でもLaravelの動作環境を簡単に作れるWINDIIオリジナルのソースコードを用意したので、実際に動かして学ぶとより深く理解できるようになります!
以下の記事を参考にご活用ください。
認可ってなに?
認可とは、ある条件を元にリソースに対する特定のアクション権限を許可することです。
ちょっとわかりにくいと思うので、例えば、ブログ投稿システムの例で考えてみましょう。

このように、Aさん、Bさん、そしてAさんが投稿した記事(リソース)があります。
もちろん、Aさんの投稿をAさんが編集したり、削除したりするのは自由ですが、Bさんが勝手に編集したり、削除するのはまずいです。
そこで、編集や削除の権限をアプリケーションで制御する必要があるというわけです。さっそく実装していきましょう!
ポリシーの作成
認可を実装するには、Laravelのポリシーという機能を使います。
以下のコマンドを実行してポリシーを作成しましょう。
php artisan make:policy ArticlePolicy --model=Article
実行すると、app/Policies/ArticlePolicy.phpというファイルが作成されます。

中身を見ると以下のようになっています。
app/Policies/ArticlePolicy.php
<?php
namespace App\Policies;
use App\User;
use App\Article;
use Illuminate\Auth\Access\HandlesAuthorization;
class ArticlePolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the article.
*
* @param \App\User $user
* @param \App\Article $article
* @return mixed
*/
public function view(User $user, Article $article)
{
//
}
/**
* Determine whether the user can create articles.
*
* @param \App\User $user
* @return mixed
*/
public function create(User $user)
{
//
}
/**
* Determine whether the user can update the article.
*
* @param \App\User $user
* @param \App\Article $article
* @return mixed
*/
public function update(User $user, Article $article)
{
//
}
/**
* Determine whether the user can delete the article.
*
* @param \App\User $user
* @param \App\Article $article
* @return mixed
*/
public function delete(User $user, Article $article)
{
//
}
/**
* Determine whether the user can restore the article.
*
* @param \App\User $user
* @param \App\Article $article
* @return mixed
*/
public function restore(User $user, Article $article)
{
//
}
/**
* Determine whether the user can permanently delete the article.
*
* @param \App\User $user
* @param \App\Article $article
* @return mixed
*/
public function forceDelete(User $user, Article $article)
{
//
}
}
ポリシーを登録する
ポリシーを作成したら、登録しましょう!
AuthServiceProvider にポリシーを登録します。
app/Providers/AuthServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Article;
use App\Policies\Articlepolicy;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
Article::class => Articlepolicy::class,
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
ポリシーを定義する
ポリシーが登録できたら、認可するアクションごとにメソッドを定義します。今回の例ですと、認証されたUserがArticleの更新をできるかどうか決めるために、ArticlePolicyのupdateメソッドを定義します。
/**
* Determine whether the user can update the article.
*
* @param \App\User $user
* @param \App\Article $article
* @return mixed
*/
public function update(User $user, Article $article)
{
return $user->id === $article->user_id;
}
ユーザが投稿を編集できる条件は、そのユーザが投稿の所有者であること、つまり
article のuser_id が 認証ユーザのidに一致すること
が条件です。これでポリシーの定義ができました。
アクションを認可する
次に、定義したポリシーを元に認可してみましょう。
app/Http/Controllers/ArticleController.phpを開いて以下を追加します。
public function __construct()
{
$this->middleware('auth')->only(['create', 'store', 'edit', 'update', 'delete']);
// 追加
$this->middleware('can:update,article')->only(['edit', 'update']);
$this->middleware('verified')->only('create');
}
書き終えたら、ログインユーザの所有していない投稿を編集しようとしてみてください。
以下のような画面になります!
Bladeテンプレート上での認可
先ほど、他の人の投稿を編集できないようにしましたが、そもそも、他の人の投稿に対しては編集ボタンを出さないようにしましょう。
resources/views/detail.blade.php を開いて以下のようにしましょう。
resources/views/detail.blade.php
@extends('layouts.app')
@section('title', $article->title)
@section('content')
<div class="card my-3">
<div class="card-body">
<h5 class="card-title">{{$article->title}}</h5>
<small>投稿日:{{($article->created_at)->format('Y/m/d')}}</small><br/>
<small>更新日:{{($article->updated_at)->format('Y/m/d')}}</small>
@can('update', $article)
<a href="/articles/{{$article->id}}/edit">編集</a>
@endcan
<p class="card-text">{{$article->content}}</p>
</div>
</div>
@endsection
ポイントは@canという命令を使って、認可制御しているところです。
@can(‘update’, $article) 〜 @endcan で囲まれている部分は、ユーザに編集権限がある場合のみ出力されます。編集権限がない投稿を開くと以下のように、編集ボタンが表示されなくなります。
以上で認可については終わりです?

WINDII

最新記事 by WINDII (全て見る)
- Canvaが最高すぎる。使い方を完全ガイド【チュートリアルあり】 - 2019年5月14日
- 人気急上昇中のLaravelをはじめよう!【徹底解説】 - 2019年4月23日
- Laravelの認可を理解して実装してみよう! - 2019年3月29日
この記事へのコメントはありません。