current userのroleカラムがadministoratorの時だけ実行できるapiを作りたい

  • ミドルウェアを独自に作る(簡単)
  • 作成したミドルウェアを通るようにapi.phpを編集する

これにより実現可能。

やりたいこと

「御託はいいから」って人は飛ばして。

「自分のやりたいこととこの記事は一致してるかまだわからん」って人は読んで。

//api.php(編集前)
 Route::get('/hoge', [HogeController::class, 'index']);//管理者だけにしか触らせたくないAPI

ドメイン/api/hoge

を呼び出した際に、ログインしているユーザーが管理者じゃなかったらブロックしたい。

//api.php(ログインしているなら誰でも実行できる書き方)
Route::middleware('auth:sanctum')->group(function(){
     Route::get('/hoge', [HogeController::class, 'index']);//管理者だけにしか触らせたくないAPI;
});

単純にログインしているかどうかの判断であればsanctum認証のミドルウェアで挟むだけでいいが、「ログインしているユーザーのroleがadministratorなら」という条件の指定方法は?

ログインしてたらOK!のようにするだけでよければ、下記の記事で解説済み。

Laravel|認証システムsanctumでapiにガードをかけるときの書き方

(今回の記事はsanctum限定の話ではないので割愛)


↓Usersテーブル

roleカラムがadministratorであるユーザーでログインしているときだけ、特定のAPIの実行を許可したい。

ユーザーの情報を取得してapi.php内にf文を書きたいところだが、api.php内では多分それができない。

やり方

新たにカーネルを作る

<?php
//プロジェクトディレクトリ/app/Http/Middleware/RoleAuthenticate.php
namespace App\\Http\\Middleware;

use App\\Providers\\RouteServiceProvider;
use Closure;
use Illuminate\\Http\\Request;
use Illuminate\\Support\\Facades\\Auth;

class RoleAuthenticate
{
    /**
     * Handle an incoming request.
     *
     * @param  \\Illuminate\\Http\\Request  $request
     * @param  \\Closure  $next
     * @param  string|null  ...$guards
     * @return mixed
     */
    public function handle(Request $request, Closure $next, ...$guards)
    {
            if (Auth::guard()->check()) {
                if(Auth::user()->role == 'administrator'){
                    //return response()->json(['status'=>'ok']);
                    return $next($request);
                }
            }
            return response()->json(['status'=>'notAdmin']);
    }
}

if(Auth::user()->role == 'administrator')

の部分で、ユーザーがadministratorかどうかを判断している。

trueなら次の処理(apiを実行)する。

そうじゃないなら'status'=>'notAdmin'と結果を返してそこで終わる。

カーネルに登録する


//プロジェクトディレクトリ/app/Http/Kernel.php

//中略
protected $routeMiddleware = [
        'auth' => \\App\\Http\\Middleware\\Authenticate::class,
       実行//追記
        'auth.basic' => \\Illuminate\\Auth\\Middleware\\AuthenticateWithBasicAuth::class,
        'cache.headers' => \\Illuminate\\Http\\Middleware\\SetCacheHeaders::class,
        'can' => \\Illuminate\\Auth\\Middleware\\Authorize::class,
        'guest' => \\App\\Http\\Middleware\\RedirectIfAuthenticated::class,
        'password.confirm' => \\Illuminate\\Auth\\Middleware\\RequirePassword::class,
        'signed' => \\Illuminate\\Routing\\Middleware\\ValidateSignature::class,
        'throttle' => \\Illuminate\\Routing\\Middleware\\ThrottleRequests::class,
        'verified' => \\Illuminate\\Auth\\Middleware\\EnsureEmailIsVerified::class,

    ];

'auth' => \\App\\Http\\Middleware\\Authenticate::を追記。

これにより、api.phpから呼び出せるようになる。

ミドルウェアを通るようにapi.phpを編集

//api.php
Route::middleware('role')->group(function(){
    Route::get('/hoge', [HogeController::class, 'index']);//管理者だけが実行できるapi
});

明らかにミドルウェアを通っていないような挙動になってしまう場合

なんか間違っててもエラーで止まらずに素通ししてしまうパターンがある。
dd()をミドルウェアの中に書いて切り分けしてみたら、止まらなかった!みたいな。

カーネルに書いているパスが間違っている

'role'=> \App\Http\Middleware\RoluAuthenticate::class,


api.phpにてroleという名称でRoleAuthenticatemiddlewareを呼び出したいのに、

Kernel.phpに記載しているファイル名がRoluAuthenticateになっているなどの場合。

また、ファイルを配置した場所によってもちゃんとパスがあっているかを確認すべき。

ミドルウェアのクラス名が間違っている

class RoleAuthenticate{・・・}

みたいな記述が10行目ぐらいにあると思うが、そこの名称がファイル名と一致しているかを確認。

ミドルウェアの使い方について

普段なんとなくでミドルウェアを使ってたけど、santctumの認証ガードも今回解説した書き方にに則っている。

Route::middleware('auth:sanctum')->group(function(){
     Route::get('/hoge', [HogeController::class, 'index']);
});

↓公式ドキュメント

Laravel 8.x ミドルウェア

管理者にしか実行させたくないAPIって、例えばどんなん?

投稿に承認機能を設けていて、その承認を行う処理

など。

承認ボタンをそもそも管理者にしか表示させないような仕組みにしていても、裏側から一般ユーザーに実行されたらあかんやん?

そんなかんじ。

無制限に質問可能なプログラミングスクール!

万が一転職できない場合は、転職保障全額返金できるコースもあり!!

無制限のメンター質問対応

 

DMMウェブキャンプでプログラミングを学習しませんか?

独学より成長スピードをブーストさせましょう!

 

まずは無料相談から!

おすすめの記事