プログラミング学習やフリーランスエンジニア情報を発信していきます。現役フリーランスエンジニア2人で運営してます!

  1. バックエンド

Laravelの認可を理解して実装してみよう!

最終更新日:2019/04/01

本記事では、ブログ投稿システムを作りながら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;
}

ユーザが投稿を編集できる条件は、そのユーザが投稿の所有者であること、つまり

articleuser_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 で囲まれている部分は、ユーザに編集権限がある場合のみ出力されます。編集権限がない投稿を開くと以下のように、編集ボタンが表示されなくなります。

以上で認可については終わりです🎉

The following two tabs change content below.

riri

25歳。 Twitter:りりー@ryudoi1 // windii socialというslackチャンネルで質問や雑談等受け付けてるので気軽に参加してください!(もちろん無料です) フリーランスになるまでの過程は こちら

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

PAGE TOP