LoginSignup
4
2

More than 3 years have passed since last update.

laravel ミドルウェア、認可と認証について、使用例の一つ「ユーザープロフィール」を挙げる

Posted at

基本的な使い方だが、記録としておく。

要件:

1.ユーザー自身で自分のプロフィールのみ編集することはできる。
2.ゲストとユーザーが他人のプロフィールを閲覧することのみ、許可される。

まず、要件②はミドルウェアの追加で満たすことはできる。

ゲストは「.../user/5/edit」にアクセスしたらログインページにリダイレクトする仕組みになっている。

class UsersController extends Controller
{
    //プロフィールを閲覧すること以外の動作は認証済のユーザーのみ行われる
    public function __construct()
    {
        $this->middleware('auth',['except'=>['show']]);
    }

    public function show(User $user)
    {
        return view('users.show',compact('user'));
    }

    public function edit(User $user)
    {
        return view('users.edit',compact('user'));
    }

    public function update(UserRequest $userRequest,ImageUploadHandler $uploader,User $user)
    {
        $data = $userRequest ->all();
        if($userRequest->avatar){
            $result = $uploader->save($userRequest->avatar,'avatars',$user->id,env('UPLOAD_SIZE'));
            if($result){
                $data['avatar'] = $result['path'];
            }
        }
        $user->update($data);
        return redirect()->route('users.show',$user->id)
            ->with('success','プロフィールを更新しました!');
    }
}

次の要件①に、本人以外のプロフィール操作を防ぐために、laravelのポリシーを使用します。

//ポリシーを生成
php artisan make:policy UserPolicy

作成されたユーザーポリシーに下記で記述

<?php

namespace App\Policies;

use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class UserPolicy
{
    use HandlesAuthorization;

     /**
     * ユーザー本人が更新可能か決める
     * @param User $currentUser
     * @param User $user
     * @return bool
     */
    public function update(User $currentUser,User $user)
    {
        return $currentUser->id === $user->id;
    }
}

次に、ポリシーを登録する。Userモデルは「app」配下でない場合、下記でモデルの設定します。

<?php

namespace App\Providers;

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

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

        // 'App\Model\User' => 'App\Policies\UserPolicy',
        Gate::guessPolicyNamesUsing(function ($modelClass){
            return 'App\Policies\\'.class_basename($modelClass).'Policy';

        });
    }
}

最後にコントローラヘルパによる認可を設定する

UserControllerに、「edit」「update」メソッドに下記のラインを追加。

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

アクションが認可されない場合、authorizeメソッドはIlluminate\Auth\Access\AuthorizationException例外を投げ、これはデフォルトでLaravelの例外ハンドラにより、403ステータスコードのHTTPレスポンスへ変換されます。

<?php

namespace App\Http\Controllers;

use App\Handlers\ImageUploadHandler;
use App\Http\Requests\UserRequest;
use App\Models\User;
use Illuminate\Http\Request;

class UsersController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth',['except'=>['show']]);
    }

    public function show(User $user)
    {
        return view('users.show',compact('user'));
    }

    public function edit(User $user)
    {
        $this->authorize('update',$user);
        return view('users.edit',compact('user'));
    }

    public function update(UserRequest $userRequest,ImageUploadHandler $uploader,User $user)
    {
        $this->authorize('update',$user);
        $data = $userRequest ->all();
        if($userRequest->avatar){
            $result = $uploader->save($userRequest->avatar,'avatars',$user->id,env('UPLOAD_SIZE'));
            if($result){
                $data['avatar'] = $result['path'];
            }
        }
        $user->update($data);
        return redirect()->route('users.show',$user->id)
            ->with('success','プロフィールを更新しました!');
    }
}

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2